home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 June / MacFormat 25.iso / Shareware City / Developers / OutOfPhase1.1 Source / OutOfPhase Folder / MainWindowStuff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-05  |  89.6 KB  |  3,085 lines  |  [TEXT/KAHL]

  1. /* MainWindowStuff.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "MainWindowStuff.h"
  31. #include "Memory.h"
  32. #include "Files.h"
  33. #include "WindowDispatcher.h"
  34. #include "Array.h"
  35. #include "CodeCenter.h"
  36. #include "TextEdit.h"
  37. #include "SampleList.h"
  38. #include "FunctionList.h"
  39. #include "AlgoSampList.h"
  40. #include "WaveTableList.h"
  41. #include "AlgoWaveTableList.h"
  42. #include "InstrList.h"
  43. #include "TrackList.h"
  44. #include "Alert.h"
  45. #include "StartupOpen.h"
  46. #include "CalculatorWindow.h"
  47. #include "GrowIcon.h"
  48. #include "Main.h"
  49. #include "DisassemblyWindow.h"
  50. #include "PcodeSystem.h"
  51. #include "DataMunging.h"
  52. #include "NumberDialog.h"
  53. #include "Numbers.h"
  54. #include "GlobalWindowMenuList.h"
  55. #include "BinaryCodedDecimal.h"
  56. #include "PlayPrefsDialog.h"
  57. #include "ImportWAVSample.h"
  58. #include "ImportRAWSample.h"
  59. #include "ImportAIFFSample.h"
  60. #include "BufferedFileInput.h"
  61. #include "BufferedFileOutput.h"
  62. #include "InteractionWindow.h"
  63. #include "ScoreEffectWindow.h"
  64. #include "EffectSpecList.h"
  65. #include "BuildInstrument.h"
  66.  
  67.  
  68. #define MINTABCOUNT (1)
  69. #define MAXTABCOUNT (255)
  70. #define DEFAULTTABSIZE (2)
  71.  
  72.  
  73. #define MAINWINSIZEX (450)
  74. #define MAINWINSIZEY (250)
  75.  
  76. /* top-left corner */
  77. #define TRACKX(W,H) (-1)
  78. #define TRACKY(W,H) (-1)
  79. #define TRACKWIDTH(W,H) ((W) / 3)
  80. #define TRACKHEIGHT(W,H) ((H) / 3)
  81.  
  82. /* top-middle */
  83. #define WAVETABLEX(W,H) (TRACKX(W,H) + TRACKWIDTH(W,H) + 1)
  84. #define WAVETABLEY(W,H) (TRACKY(W,H))
  85. #define WAVETABLEWIDTH(W,H) (((W) - WAVETABLEX(W,H)) / 2)
  86. #define WAVETABLEHEIGHT(W,H) (TRACKHEIGHT(W,H))
  87.  
  88. /* top-right corner */
  89. #define SAMPLEX(W,H) (WAVETABLEX(W,H) + WAVETABLEWIDTH(W,H) + 1)
  90. #define SAMPLEY(W,H) (WAVETABLEY(W,H))
  91. #define SAMPLEWIDTH(W,H) ((W) - SAMPLEX(W,H) + 1)
  92. #define SAMPLEHEIGHT(W,H) (WAVETABLEHEIGHT(W,H))
  93.  
  94. /* middle-left */
  95. #define INSTRUMENTX(W,H) (TRACKX(W,H))
  96. #define INSTRUMENTY(W,H) (TRACKY(W,H) + TRACKHEIGHT(W,H))
  97. #define INSTRUMENTWIDTH(W,H) (TRACKWIDTH(W,H))
  98. #define INSTRUMENTHEIGHT(W,H) (((H) - INSTRUMENTY(W,H)) / 2)
  99.  
  100. /* middle-middle */
  101. #define ALGOWAVETABLEX(W,H) (WAVETABLEX(W,H))
  102. #define ALGOWAVETABLEY(W,H) (INSTRUMENTY(W,H))
  103. #define ALGOWAVETABLEWIDTH(W,H) (WAVETABLEWIDTH(W,H))
  104. #define ALGOWAVETABLEHEIGHT(W,H) (INSTRUMENTHEIGHT(W,H))
  105.  
  106. /* middle-right */
  107. #define ALGOSAMPLEX(W,H) (SAMPLEX(W,H))
  108. #define ALGOSAMPLEY(W,H) (ALGOWAVETABLEY(W,H))
  109. #define ALGOSAMPLEWIDTH(W,H) (SAMPLEWIDTH(W,H))
  110. #define ALGOSAMPLEHEIGHT(W,H) (ALGOWAVETABLEHEIGHT(W,H))
  111.  
  112. /* bottom-left corner */
  113. #define FUNCTIONX(W,H) (INSTRUMENTX(W,H))
  114. #define FUNCTIONY(W,H) (INSTRUMENTY(W,H) + INSTRUMENTHEIGHT(W,H))
  115. #define FUNCTIONWIDTH(W,H) (INSTRUMENTWIDTH(W,H))
  116. #define FUNCTIONHEIGHT(W,H) ((H) - FUNCTIONY(W,H) + 1)
  117.  
  118. /* bottom-middle and bottom-right corner */
  119. #define COMMENTX(W,H) (FUNCTIONX(W,H) + FUNCTIONWIDTH(W,H) + 1)
  120. #define COMMENTY(W,H) (FUNCTIONY(W,H) + 1)
  121. #define COMMENTWIDTH(W,H) ((W) - COMMENTX(W,H) + 1)
  122. #define COMMENTHEIGHT(W,H) (FUNCTIONHEIGHT(W,H) - 1)
  123.  
  124.  
  125. /* this structure contains all the information for a document */
  126. struct MainWindowRec
  127.     {
  128.         WinType*                        ScreenID;
  129.         MyBoolean                        EverBeenSaved;
  130.         FileSpec*                        TheFileLocation; /* only valid if EverBeenSaved is true */
  131.         FileType*                        TheFile; /* only valid if EverBeenSaved is true */
  132.         GenericWindowRec*        MyGenericWindow; /* how the window event dispatcher knows us */
  133.         MenuItemType*                MyMenuItem;
  134.  
  135.         FileSpec*                        DeleteUndoFileLocation; /* NIL = none */
  136.         FileType*                        DeleteUndoFile; /* NIL = none */
  137.  
  138.         ArrayRec*                        ListOfCalcWindows;
  139.         ArrayRec*                        ListOfDisassemblies;
  140.         CodeCenterRec*            CodeCenter; /* keeps all the object code */
  141.         InteractionWindowRec*    InteractionWindow;
  142.  
  143.         /* generic control parameters */
  144.         long                                TabSize;
  145.         TextEditRec*                CommentInfo;
  146.  
  147.         /* score data */
  148.         SampleListRec*            SampleList;
  149.         FunctionListRec*        FunctionList;
  150.         AlgoSampListRec*        AlgoSampList;
  151.         WaveTableListRec*        WaveTableList;
  152.         AlgoWaveTableListRec*    AlgoWaveTableList;
  153.         InstrListRec*                InstrumentList;
  154.         TrackListRec*                TrackList;
  155.  
  156.         MyBoolean                        StuffModified;
  157.  
  158.         /* playback preferences */
  159.         MyBoolean                        StereoPlayback;
  160.         MyBoolean                        SurroundEncoding;
  161.         long                                SamplingRate;
  162.         long                                EnvelopeUpdateRate;
  163.         LargeBCDType                DefaultBeatsPerMinute;
  164.         LargeBCDType                OverallVolumeScalingFactor;
  165.         OutputNumBitsType        OutputNumBits;
  166.         MyBoolean                        InterpolateOverTime;
  167.         MyBoolean                        InterpolateAcrossWaves;
  168.         LargeBCDType                ScanningGap;
  169.         LargeBCDType                BufferDuration;
  170.         MyBoolean                        ClipWarning;
  171.  
  172.         char*                                ScoreEffects;
  173.         ScoreEffectWindowRec*    ScoreEffectsEditWindow;
  174.     };
  175.  
  176.  
  177. static ArrayRec*                ListOfDocuments = NIL;
  178.  
  179.  
  180. /* initialize internal data structures for documents */
  181. MyBoolean                        InitializeDocuments(void)
  182.     {
  183.         APRINT(("+InitializeDocuments"));
  184.         ListOfDocuments = NewArray();
  185.         if (ListOfDocuments == NIL)
  186.             {
  187.                 APRINT(("-InitializeDocuments failed"));
  188.                 return False;
  189.             }
  190.         APRINT(("-InitializeDocuments"));
  191.         return True;
  192.     }
  193.  
  194.  
  195. /* clean up any internal data structures used for documents */
  196. void                                ShutdownDocuments(void)
  197.     {
  198.         APRINT(("+ShutdownDocuments"));
  199.         ERROR(ArrayGetLength(ListOfDocuments) != 0,PRERR(AllowResume,
  200.             "ShutdownDocuments:  Not all documents disposed of"));
  201.         DisposeArray(ListOfDocuments);
  202.         APRINT(("-ShutdownDocuments"));
  203.     }
  204.  
  205.  
  206. /* open a new document window and load the document in.  the function takes */
  207. /* ownership of the file specification. */
  208. void                                OpenDocument(FileSpec* TheFile)
  209.     {
  210.         MainWindowRec*        Window;
  211.         MyBoolean                    MemoryError = True;
  212.  
  213.         /* allocation */
  214.         Window = (MainWindowRec*)AllocPtrCanFail(sizeof(MainWindowRec),"MainWindowRec");
  215.         if (Window == NIL)
  216.             {
  217.              FailurePoint1:
  218.                 if (MemoryError)
  219.                     {
  220.                         AlertHalt("There is not enough memory available to open the document.",NIL);
  221.                     }
  222.                 if (TheFile != NIL)
  223.                     {
  224.                         DisposeFileSpec(TheFile);
  225.                     }
  226.                 return;
  227.             }
  228.         if (!ArrayAppendElement(ListOfDocuments,Window))
  229.             {
  230.              FailurePoint2:
  231.                 ReleasePtr((char*)Window);
  232.                 goto FailurePoint1;
  233.             }
  234.  
  235.         /* constructing members */
  236.  
  237.         Window->TabSize = DEFAULTTABSIZE;
  238.  
  239.         Window->CodeCenter = NewCodeCenter();
  240.         if (Window->CodeCenter == NIL)
  241.             {
  242.              FailurePoint3:
  243.                 ArrayDeleteElement(ListOfDocuments,ArrayFindElement(ListOfDocuments,Window));
  244.                 goto FailurePoint2;
  245.             }
  246.  
  247.         Window->ScreenID = MakeNewWindow(eDocumentWindow,eWindowClosable,
  248.             eWindowZoomable,eWindowResizable,4 + WindowOtherEdgeWidths(eDocumentWindow),
  249.             4 + WindowTitleBarHeight(eDocumentWindow),MAINWINSIZEX,MAINWINSIZEY,
  250.             (void (*)(void*))&MainWindowUpdator,Window);
  251.         if (Window->ScreenID == 0)
  252.             {
  253.              FailurePoint4:
  254.                 DisposeCodeCenter(Window->CodeCenter);
  255.                 goto FailurePoint3;
  256.             }
  257.  
  258.         Window->CommentInfo = NewTextEdit(Window->ScreenID,
  259.             (TEScrollType)(eTEHScrollBar | eTEVScrollBar),GetScreenFont(),9,
  260.             COMMENTX(MAINWINSIZEX,MAINWINSIZEY),COMMENTY(MAINWINSIZEX,MAINWINSIZEY),
  261.             COMMENTWIDTH(MAINWINSIZEX,MAINWINSIZEY),COMMENTHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  262.         if (Window->CommentInfo == NIL)
  263.             {
  264.              FailurePoint5:
  265.                 KillWindow(Window->ScreenID);
  266.                 goto FailurePoint4;
  267.             }
  268.  
  269.         Window->SampleList = NewSampleList(Window,Window->CodeCenter,
  270.             Window->ScreenID,SAMPLEX(MAINWINSIZEX,MAINWINSIZEY),
  271.             SAMPLEY(MAINWINSIZEX,MAINWINSIZEY),SAMPLEWIDTH(MAINWINSIZEX,MAINWINSIZEY),
  272.             SAMPLEHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  273.         if (Window->SampleList == NIL)
  274.             {
  275.              FailurePoint6:
  276.                 DisposeTextEdit(Window->CommentInfo);
  277.                 goto FailurePoint5;
  278.             }
  279.  
  280.         Window->FunctionList = NewFunctionList(Window,Window->CodeCenter,
  281.             Window->ScreenID,FUNCTIONX(MAINWINSIZEX,MAINWINSIZEY),
  282.             FUNCTIONY(MAINWINSIZEX,MAINWINSIZEY),FUNCTIONWIDTH(MAINWINSIZEX,MAINWINSIZEY),
  283.             FUNCTIONHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  284.         if (Window->FunctionList == NIL)
  285.             {
  286.              FailurePoint7:
  287.                 DisposeSampleList(Window->SampleList);
  288.                 goto FailurePoint6;
  289.             }
  290.  
  291.         Window->AlgoSampList = NewAlgoSampList(Window,Window->CodeCenter,
  292.             Window->ScreenID,ALGOSAMPLEX(MAINWINSIZEX,MAINWINSIZEY),
  293.             ALGOSAMPLEY(MAINWINSIZEX,MAINWINSIZEY),
  294.             ALGOSAMPLEWIDTH(MAINWINSIZEX,MAINWINSIZEY),
  295.             ALGOSAMPLEHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  296.         if (Window->AlgoSampList == NIL)
  297.             {
  298.              FailurePoint8:
  299.                 DisposeFunctionList(Window->FunctionList);
  300.                 goto FailurePoint7;
  301.             }
  302.  
  303.         Window->WaveTableList = NewWaveTableList(Window,Window->CodeCenter,
  304.             Window->ScreenID,WAVETABLEX(MAINWINSIZEX,MAINWINSIZEY),
  305.             WAVETABLEY(MAINWINSIZEX,MAINWINSIZEY),WAVETABLEWIDTH(MAINWINSIZEX,MAINWINSIZEY),
  306.             WAVETABLEHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  307.         if (Window->WaveTableList == NIL)
  308.             {
  309.              FailurePoint9:
  310.                 DisposeAlgoSampList(Window->AlgoSampList);
  311.                 goto FailurePoint8;
  312.             }
  313.  
  314.         Window->AlgoWaveTableList = NewAlgoWaveTableList(Window,Window->CodeCenter,
  315.             Window->ScreenID,ALGOWAVETABLEX(MAINWINSIZEX,MAINWINSIZEY),
  316.             ALGOWAVETABLEY(MAINWINSIZEX,MAINWINSIZEY),
  317.             ALGOWAVETABLEWIDTH(MAINWINSIZEX,MAINWINSIZEY),
  318.             ALGOWAVETABLEHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  319.         if (Window->AlgoWaveTableList == NIL)
  320.             {
  321.              FailurePoint10:
  322.                 DisposeWaveTableList(Window->WaveTableList);
  323.                 goto FailurePoint9;
  324.             }
  325.  
  326.         Window->InstrumentList = NewInstrList(Window,Window->CodeCenter,
  327.             Window->ScreenID,INSTRUMENTX(MAINWINSIZEX,MAINWINSIZEY),
  328.             INSTRUMENTY(MAINWINSIZEX,MAINWINSIZEY),INSTRUMENTWIDTH(MAINWINSIZEX,MAINWINSIZEY),
  329.             INSTRUMENTHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  330.         if (Window->InstrumentList == NIL)
  331.             {
  332.              FailurePoint11:
  333.                 DisposeAlgoWaveTableList(Window->AlgoWaveTableList);
  334.                 goto FailurePoint10;
  335.             }
  336.  
  337.         Window->TrackList = NewTrackList(Window,Window->CodeCenter,
  338.             Window->ScreenID,TRACKX(MAINWINSIZEX,MAINWINSIZEY),TRACKY(MAINWINSIZEX,MAINWINSIZEY),
  339.             TRACKWIDTH(MAINWINSIZEX,MAINWINSIZEY),TRACKHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  340.         if (Window->TrackList == NIL)
  341.             {
  342.              FailurePoint12:
  343.                 DisposeInstrList(Window->InstrumentList);
  344.                 goto FailurePoint11;
  345.             }
  346.  
  347.         Window->ListOfCalcWindows = NewArray();
  348.         if (Window->ListOfCalcWindows == NIL)
  349.             {
  350.              FailurePoint13:
  351.                 DisposeTrackList(Window->TrackList);
  352.                 goto FailurePoint12;
  353.             }
  354.  
  355.         Window->ListOfDisassemblies = NewArray();
  356.         if (Window->ListOfDisassemblies == NIL)
  357.             {
  358.              FailurePoint14:
  359.                 DisposeArray(Window->ListOfCalcWindows);
  360.                 goto FailurePoint13;
  361.             }
  362.  
  363.         Window->MyGenericWindow = CheckInNewWindow(Window->ScreenID,Window,
  364.             (void (*)(void*,MyBoolean,OrdType,OrdType,ModifierFlags))&MainWindowDoIdle,
  365.             (void (*)(void*))&MainWindowBecomeActive,
  366.             (void (*)(void*))&MainWindowBecomeInactive,
  367.             (void (*)(void*))&MainWindowJustResized,
  368.             (void (*)(OrdType,OrdType,ModifierFlags,void*))&MainWindowDoMouseDown,
  369.             (void (*)(unsigned char,ModifierFlags,void*))&MainWindowDoKeyDown,
  370.             (void (*)(void*))&MainWindowClose,
  371.             (void (*)(void*))&MainWindowMenuSetup,
  372.             (void (*)(void*,MenuItemType*))&MainWindowDoMenuCommand);
  373.         if (Window->MyGenericWindow == NIL)
  374.             {
  375.              FailurePoint15:
  376.                 DisposeArray(Window->ListOfDisassemblies);
  377.                 goto FailurePoint14;
  378.             }
  379.  
  380.         Window->MyMenuItem = MakeNewMenuItem(mmWindowMenu,"x",0);
  381.         if (Window->MyMenuItem == NIL)
  382.             {
  383.              FailurePoint16:
  384.                 CheckOutDyingWindow(Window->MyGenericWindow);
  385.                 goto FailurePoint15;
  386.             }
  387.         if (!RegisterWindowMenuItem(Window->MyMenuItem,(void (*)(void*))&ActivateThisWindow,
  388.             Window->ScreenID))
  389.             {
  390.              FailurePoint17:
  391.                 KillMenuItem(Window->MyMenuItem);
  392.                 goto FailurePoint16;
  393.             }
  394.  
  395.         Window->ScoreEffects = StringToBlockCopy("#score effects\x0a");
  396.         if (Window->ScoreEffects == NIL)
  397.             {
  398.              FailurePoint18:
  399.                 DeregisterWindowMenuItem(Window->MyMenuItem);
  400.                 goto FailurePoint17;
  401.             }
  402.         SetTag(Window->ScoreEffects,"ScoreEffects");
  403.  
  404.         Window->StereoPlayback = True;
  405.         Window->SurroundEncoding = False;
  406.         Window->SamplingRate = 44100;
  407.         Window->EnvelopeUpdateRate = 441;
  408.         Window->DefaultBeatsPerMinute = Double2LargeBCD(120);
  409.         Window->OverallVolumeScalingFactor = Double2LargeBCD(1);
  410.         Window->OutputNumBits = eOutput16Bits;
  411.         Window->InterpolateOverTime = True;
  412.         Window->InterpolateAcrossWaves = True;
  413.         Window->StuffModified = False;
  414.         Window->ScanningGap = Double2LargeBCD(2);
  415.         Window->BufferDuration = Double2LargeBCD(8);
  416.         Window->ClipWarning = True;
  417.  
  418.         Window->DeleteUndoFileLocation = NIL;
  419.         Window->DeleteUndoFile = NIL;
  420.  
  421.         Window->InteractionWindow = NIL;
  422.  
  423.         Window->ScoreEffectsEditWindow = NIL;
  424.  
  425.         /* reading the data or making an empty instrument */
  426.         if (TheFile == NIL)
  427.             {
  428.                 /* create a new empty one */
  429.                 Window->EverBeenSaved = False;
  430.             }
  431.          else
  432.             {
  433.                 FileType*                    FileDesc;
  434.  
  435.                 /* read a file in and update the file refnum and location variables */
  436.                 if (OpenFile(TheFile,&FileDesc,eReadAndWrite))
  437.                     {
  438.                         BufferedInputRec*    InputFileThang;
  439.  
  440.                         InputFileThang = NewBufferedInput(FileDesc);
  441.                         if (InputFileThang == NIL)
  442.                             {
  443.                                 ReleasePtr(Window->ScoreEffects);
  444.                                 goto FailurePoint18;
  445.                             }
  446.                          else
  447.                             {
  448.                                 FileLoadingErrors    Error;
  449.                                 short                            FormatVersionNumber;
  450.  
  451.                                 SetWatchCursor();
  452.                                 Error = MainWindowReadData(Window,InputFileThang,&FormatVersionNumber);
  453.                                 if (Error == eFileLoadNoError)
  454.                                     {
  455.                                         if (FormatVersionNumber == 1)
  456.                                             {
  457.                                                 /* old file organization */
  458.                                                 Error = SampleListReadData(Window->SampleList,InputFileThang);
  459.                                                 if (Error == eFileLoadNoError)
  460.                                                     {
  461.                                                         Error = FunctionListReadData(Window->FunctionList,
  462.                                                             InputFileThang);
  463.                                                         if (Error == eFileLoadNoError)
  464.                                                             {
  465.                                                                 Error = AlgoSampListReadData(Window->AlgoSampList,
  466.                                                                     InputFileThang);
  467.                                                                 if (Error == eFileLoadNoError)
  468.                                                                     {
  469.                                                                         Error = WaveTableListReadData(Window->WaveTableList,
  470.                                                                             InputFileThang);
  471.                                                                         if (Error == eFileLoadNoError)
  472.                                                                             {
  473.                                                                                 Error = AlgoWaveTableListReadData(
  474.                                                                                     Window->AlgoWaveTableList,InputFileThang);
  475.                                                                                 if (Error == eFileLoadNoError)
  476.                                                                                     {
  477.                                                                                         Error = InstrListReadData(Window->InstrumentList,
  478.                                                                                             InputFileThang);
  479.                                                                                         if (Error == eFileLoadNoError)
  480.                                                                                             {
  481.                                                                                                 Error = TrackListReadData(Window->TrackList,
  482.                                                                                                     InputFileThang);
  483.                                                                                             }
  484.                                                                                     }
  485.                                                                             }
  486.                                                                     }
  487.                                                             }
  488.                                                     }
  489.                                             }
  490.                                          else
  491.                                             {
  492.                                                 /* new file organization, with samples moved to end to help */
  493.                                                 /* compression programs */
  494.                                                 Error = TrackListReadData(Window->TrackList,InputFileThang);
  495.                                                 if (Error == eFileLoadNoError)
  496.                                                     {
  497.                                                         Error = FunctionListReadData(Window->FunctionList,
  498.                                                             InputFileThang);
  499.                                                         if (Error == eFileLoadNoError)
  500.                                                             {
  501.                                                                 Error = AlgoSampListReadData(Window->AlgoSampList,
  502.                                                                     InputFileThang);
  503.                                                                 if (Error == eFileLoadNoError)
  504.                                                                     {
  505.                                                                         Error = AlgoWaveTableListReadData(
  506.                                                                             Window->AlgoWaveTableList,InputFileThang);
  507.                                                                         if (Error == eFileLoadNoError)
  508.                                                                             {
  509.                                                                                 Error = InstrListReadData(Window->InstrumentList,
  510.                                                                                     InputFileThang);
  511.                                                                                 if (Error == eFileLoadNoError)
  512.                                                                                     {
  513.                                                                                         Error = WaveTableListReadData(Window->WaveTableList,
  514.                                                                                             InputFileThang);
  515.                                                                                         if (Error == eFileLoadNoError)
  516.                                                                                             {
  517.                                                                                                 Error = SampleListReadData(Window->SampleList,
  518.                                                                                                     InputFileThang);
  519.                                                                                             }
  520.                                                                                     }
  521.                                                                             }
  522.                                                                     }
  523.                                                             }
  524.                                                     }
  525.                                             }
  526.                                     }
  527.                                 switch (Error)
  528.                                     {
  529.                                         default:
  530.                                             EXECUTE(PRERR(ForceAbort,"OpenDocument:  bad error code"));
  531.                                             break;
  532.                                         case eFileLoadNoError:
  533.                                             break;
  534.                                         case eFileLoadBadFormat:
  535.                                             AlertHalt("The file format is unrecognized.",NIL);
  536.                                             break;
  537.                                         case eFileLoadDiskError:
  538.                                             AlertHalt("A disk error occurred and the file could not be "
  539.                                                 "completely loaded.",NIL);
  540.                                             break;
  541.                                         case eFileLoadOutOfMemory:
  542.                                             AlertHalt("There is not enough memory available to completely "
  543.                                                 "load the file.  Try closing windows or quitting other "
  544.                                                 "applications to make more memory available.",NIL);
  545.                                             break;
  546.                                     }
  547.                             }
  548.                         EndBufferedInput(InputFileThang);
  549.                         MainWindowDeselectAllOtherStringLists(Window,NIL/*deselect all*/);
  550.                     }
  551.                  else
  552.                     {
  553.                         MemoryError = False;
  554.                         AlertHalt("Unable to open file for reading.",NIL);
  555.                         ReleasePtr(Window->ScoreEffects);
  556.                         goto FailurePoint18;
  557.                     }
  558.                 Window->EverBeenSaved = True;
  559.                 Window->TheFileLocation = TheFile;
  560.                 Window->TheFile = FileDesc;
  561.             }
  562.  
  563.         MainWindowDispatchNameChange(Window);
  564.     }
  565.  
  566.  
  567. /* save the document into the current file.  if it hasn't been saved, then call SaveAs */
  568. /* it returns False if it fails. */
  569. MyBoolean                        SaveDocument(MainWindowRec* Window)
  570.     {
  571.         CheckPtrExistence(Window);
  572.         if (!Window->EverBeenSaved)
  573.             {
  574.                 return SaveDocumentAs(Window);
  575.             }
  576.          else
  577.             {
  578.                 FileType*                    TempFile;
  579.                 FileSpec*                    TempFileLocation;
  580.                 BufferedOutputRec*    OutputFileThang;
  581.                 FileLoadingErrors    Error;
  582.  
  583.                 /* create new file and write the data out here */
  584.                 /* create a temporary file in the same directory */
  585.                 TempFileLocation = NewTempFileInTheSameDirectory(Window->TheFileLocation);
  586.                 if (TempFileLocation == NIL)
  587.                     {
  588.                      FailurePoint1:
  589.                         AlertHalt("Unable to write out the data.",NIL);
  590.                         return False;
  591.                     }
  592.                 /* open the file */
  593.                 if (!OpenFile(TempFileLocation,&TempFile,eReadAndWrite))
  594.                     {
  595.                      FailurePoint2:
  596.                         DisposeFileSpec(TempFileLocation);
  597.                         goto FailurePoint1;
  598.                     }
  599.                 /* write all the data out */
  600.                 OutputFileThang = NewBufferedOutput(TempFile);
  601.                 if (OutputFileThang == NIL)
  602.                     {
  603.                      FailurePoint3:
  604.                         CloseFile(TempFile);
  605.                         DeleteFile(TempFileLocation);
  606.                         goto FailurePoint2;
  607.                     }
  608.                 SetWatchCursor();
  609.                 Error = MainWindowWriteData(Window,OutputFileThang);
  610.                 if (Error == eFileLoadNoError)
  611.                     {
  612.                         Error = TrackListWriteData(Window->TrackList,OutputFileThang);
  613.                         if (Error == eFileLoadNoError)
  614.                             {
  615.                                 Error = FunctionListWriteData(Window->FunctionList,OutputFileThang);
  616.                                 if (Error == eFileLoadNoError)
  617.                                     {
  618.                                         Error = AlgoSampListWriteData(Window->AlgoSampList,OutputFileThang);
  619.                                         if (Error == eFileLoadNoError)
  620.                                             {
  621.                                                 Error = AlgoWaveTableListWriteData(Window->AlgoWaveTableList,
  622.                                                     OutputFileThang);
  623.                                                 if (Error == eFileLoadNoError)
  624.                                                     {
  625.                                                         Error = InstrListWriteData(Window->InstrumentList,
  626.                                                             OutputFileThang);
  627.                                                         if (Error == eFileLoadNoError)
  628.                                                             {
  629.                                                                 Error = WaveTableListWriteData(Window->WaveTableList,
  630.                                                                     OutputFileThang);
  631.                                                                 if (Error == eFileLoadNoError)
  632.                                                                     {
  633.                                                                         Error = SampleListWriteData(Window->SampleList,
  634.                                                                             OutputFileThang);
  635.                                                                         if (Error == eFileLoadNoError)
  636.                                                                             {
  637.                                                                                 if (EndBufferedOutput(OutputFileThang))
  638.                                                                                     {
  639.                                                                                         Error = eFileLoadNoError;
  640.                                                                                     }
  641.                                                                                  else
  642.                                                                                     {
  643.                                                                                         Error = eFileLoadDiskError;
  644.                                                                                     }
  645.                                                                             }
  646.                                                                     }
  647.                                                             }
  648.                                                     }
  649.                                             }
  650.                                     }
  651.                             }
  652.                     }
  653.                 switch (Error)
  654.                     {
  655.                         default:
  656.                             EXECUTE(PRERR(ForceAbort,"OpenDocument:  bad error code"));
  657.                             break;
  658.                         case eFileLoadNoError:
  659.                             break;
  660.                         case eFileLoadDiskError:
  661.                             AlertHalt("A disk error occurred and the file could not be saved.",NIL);
  662.                             goto FailurePoint3;
  663.                         case eFileLoadOutOfMemory:
  664.                             AlertHalt("There is not enough memory available to save the file.  "
  665.                                 "Try closing windows or quitting other applications to make more "
  666.                                 "memory available.",NIL);
  667.                             goto FailurePoint3;
  668.                     }
  669.                 FlushLocalBuffers(TempFile);
  670.                 /* swap the files on the disk */
  671.                 if (!SwapFileDataForks(TempFileLocation,Window->TheFileLocation,TempFile,
  672.                     &(Window->TheFile)))
  673.                     {
  674.                         /* if this fails, then the parameters are unaltered */
  675.                         goto FailurePoint3;
  676.                     }
  677.                 /* at this point, Window->TheFile has been fixed up, TempFile is closed, */
  678.                 /* and we need to dispose TempFileLocation */
  679.                 DisposeFileSpec(TempFileLocation);
  680.                 /* mark the data to indicate that it has been saved. */
  681.                 FunctionListMarkAllObjectsSaved(Window->FunctionList);
  682.                 SampleListMarkAllObjectsSaved(Window->SampleList);
  683.                 AlgoSampListMarkAllObjectsSaved(Window->AlgoSampList);
  684.                 WaveTableListMarkAllObjectsSaved(Window->WaveTableList);
  685.                 AlgoWaveTableListMarkAllObjectsSaved(Window->AlgoWaveTableList);
  686.                 InstrListMarkAllObjectsSaved(Window->InstrumentList);
  687.                 TrackListMarkAllObjectsSaved(Window->TrackList);
  688.                 TextEditHasBeenSaved(Window->CommentInfo);
  689.                 Window->StuffModified = False;
  690.                 /* return true since it saved correctly */
  691.                 return True;
  692.             }
  693.         EXECUTE(PRERR(ForceAbort,"SaveDocument:  control reached end of function"));
  694.     }
  695.  
  696.  
  697. /* close all open documents, subject to the user's ok */
  698. void                                DoCloseAllQuitPending(void)
  699.     {
  700.         while (ArrayGetLength(ListOfDocuments) > 0)
  701.             {
  702.                 MainWindowRec*        Window;
  703.  
  704.                 Window = (MainWindowRec*)ArrayGetElement(ListOfDocuments,0);
  705.                 ActivateThisWindow(Window->ScreenID);
  706.                 if (!CloseDocument(Window))
  707.                     {
  708.                         /* user cancelled */
  709.                         AbortQuitInProgress();
  710.                         return;
  711.                     }
  712.                 /* else keep going */
  713.             }
  714.     }
  715.  
  716.  
  717. /* close a document.  If the user cancelled, then return False, otherwise True */
  718. MyBoolean                        CloseDocument(MainWindowRec* Window)
  719.     {
  720.         long                Scan;
  721.  
  722.         CheckPtrExistence(Window);
  723.         if (HasDocumentBeenModified(Window))
  724.             {
  725.                 /* hafta ask permission */
  726.                 YesNoCancelType        WhatToDo;
  727.                 char*                            Filename;
  728.                 char*                            XFilename;
  729.  
  730.                 XFilename = GetCopyOfDocumentName(Window);
  731.                 if (XFilename == NIL)
  732.                     {
  733.                      FailurePoint1:
  734.                         AlertHalt("There is not enough memory to close the document.",NIL);
  735.                         return False;
  736.                     }
  737.                 Filename = BlockToStringCopy(XFilename);
  738.                 ReleasePtr(XFilename);
  739.                 if (Filename == NIL)
  740.                     {
  741.                         goto FailurePoint1;
  742.                     }
  743.                 WhatToDo = AskYesNoCancel("Save changes to document '_'?",
  744.                     Filename,"Save","Don't Save","Cancel");
  745.                 ReleasePtr(Filename);
  746.                 if (WhatToDo == eYes)
  747.                     {
  748.                         if (!SaveDocument(Window))
  749.                             {
  750.                                 /* save was cancelled or failed */
  751.                                 return False;
  752.                             }
  753.                     }
  754.                 else if (WhatToDo == eCancel)
  755.                     {
  756.                         return False; /* user cancelled */
  757.                     }
  758.                 /* fall through to deletion point */
  759.             }
  760.  
  761.         if (Window->DeleteUndoFileLocation != NIL)
  762.             {
  763.                 CloseFile(Window->DeleteUndoFile);
  764.                 DeleteFile(Window->DeleteUndoFileLocation);
  765.                 DisposeFileSpec(Window->DeleteUndoFileLocation);
  766.             }
  767.  
  768.         if (Window->InteractionWindow != NIL)
  769.             {
  770.                 DisposeInteractionWindow(Window->InteractionWindow);
  771.                 ERROR(Window->InteractionWindow != NIL,PRERR(ForceAbort,
  772.                     "CloseDocument:  DisposeInteractionWindow didn't notify"));
  773.             }
  774.  
  775.         /* perform the data deletion here */
  776.         DisposeFunctionList(Window->FunctionList);
  777.         DisposeSampleList(Window->SampleList);
  778.         DisposeAlgoSampList(Window->AlgoSampList);
  779.         DisposeWaveTableList(Window->WaveTableList);
  780.         DisposeAlgoWaveTableList(Window->AlgoWaveTableList);
  781.         DisposeInstrList(Window->InstrumentList);
  782.         DisposeTrackList(Window->TrackList);
  783.  
  784.         /* must delete effect window before deleting effect string */
  785.         if (Window->ScoreEffectsEditWindow != NIL)
  786.             {
  787.                 DisposeScoreEffectWindow(Window->ScoreEffectsEditWindow);
  788.             }
  789.         ERROR(Window->ScoreEffectsEditWindow != NIL,PRERR(ForceAbort,
  790.             "CloseDocument:  disposed score effects window but it didn't notify"));
  791.  
  792.         DisposeTextEdit(Window->CommentInfo);
  793.  
  794.         for (Scan = 0; Scan < ArrayGetLength(Window->ListOfCalcWindows); Scan += 1)
  795.             {
  796.                 DisposeCalculatorWindow((CalcWindowRec*)ArrayGetElement(
  797.                     Window->ListOfCalcWindows,Scan));
  798.             }
  799.         DisposeArray(Window->ListOfCalcWindows);
  800.  
  801.         for (Scan = 0; Scan < ArrayGetLength(Window->ListOfDisassemblies); Scan += 1)
  802.             {
  803.                 DisposeDisassemblyWindow((DisaWindowRec*)ArrayGetElement(
  804.                     Window->ListOfDisassemblies,Scan));
  805.             }
  806.         DisposeArray(Window->ListOfDisassemblies);
  807.  
  808.         /* delete object code */
  809.         DisposeCodeCenter(Window->CodeCenter);
  810.  
  811.         ReleasePtr(Window->ScoreEffects);
  812.  
  813.         DeregisterWindowMenuItem(Window->MyMenuItem);
  814.         KillMenuItem(Window->MyMenuItem);
  815.         CheckOutDyingWindow(Window->MyGenericWindow);
  816.         KillWindow(Window->ScreenID);
  817.         if (Window->EverBeenSaved)
  818.             {
  819.                 CloseFile(Window->TheFile);
  820.                 DisposeFileSpec(Window->TheFileLocation);
  821.             }
  822.         ERROR(ArrayFindElement(ListOfDocuments,Window) < 0,PRERR(ForceAbort,
  823.             "CloseDocument:  couldn't find document in the list"));
  824.         ArrayDeleteElement(ListOfDocuments,ArrayFindElement(ListOfDocuments,Window));
  825.         ReleasePtr((char*)Window);
  826.         return True;
  827.     }
  828.  
  829.  
  830. /* save the document into a new file (don't disturb the current one).  returns False */
  831. /* if it fails.  this function calls SaveDocument() to do the work. */
  832. MyBoolean                        SaveDocumentAs(MainWindowRec* Window)
  833.     {
  834.         FileSpec*                    NewWhere;
  835.         char*                            FilenameNull;
  836.         char*                            StringTempFileNameThing;
  837.  
  838.         CheckPtrExistence(Window);
  839.         StringTempFileNameThing = GetCopyOfDocumentName(Window);
  840.         if (StringTempFileNameThing == NIL)
  841.             {
  842.              FailurePoint1:
  843.                 AlertHalt("There is not enough memory to save the document.",NIL);
  844.                 return False;
  845.             }
  846.         FilenameNull = BlockToStringCopy(StringTempFileNameThing);
  847.         ReleasePtr(StringTempFileNameThing);
  848.         if (FilenameNull == NIL)
  849.             {
  850.                 goto FailurePoint1;
  851.             }
  852.         /* where do they want to save it */
  853.         NewWhere = PutFile(FilenameNull);
  854.         ReleasePtr(FilenameNull);
  855.         if (NewWhere != NIL)
  856.             {
  857.                 FileType*                    NewFile;
  858.                 char*                            XFilename;
  859.                 MyBoolean                    SaveWasSuccessful;
  860.  
  861.                 XFilename = ExtractFileName(NewWhere);
  862.                 if (XFilename == NIL)
  863.                     {
  864.                         goto FailurePoint1;
  865.                     }
  866.                 FilenameNull = BlockToStringCopy(XFilename);
  867.                 ReleasePtr(XFilename);
  868.                 if (FilenameNull == NIL)
  869.                     {
  870.                         goto FailurePoint1;
  871.                     }
  872.                 if (!CreateFile(NewWhere,ApplicationCreator,ApplicationFileType))
  873.                     {
  874.                         AlertHalt("Couldn't create the file '_'.",FilenameNull);
  875.                         ReleasePtr(FilenameNull);
  876.                         return False;
  877.                     }
  878.                 if (!OpenFile(NewWhere,&NewFile,eReadAndWrite))
  879.                     {
  880.                         AlertHalt("Couldn't open the file '_'.",FilenameNull);
  881.                         ReleasePtr(FilenameNull);
  882.                         return False;
  883.                     }
  884.                 if (Window->EverBeenSaved)
  885.                     {
  886.                         CloseFile(Window->TheFile);
  887.                         DisposeFileSpec(Window->TheFileLocation);
  888.                         Window->EverBeenSaved = False;
  889.                     }
  890.                 Window->EverBeenSaved = True;
  891.                 Window->TheFileLocation = NewWhere;
  892.                 Window->TheFile = NewFile;
  893.                 ReleasePtr(FilenameNull);
  894.                 SaveWasSuccessful = SaveDocument(Window);
  895.                 if (!SaveWasSuccessful)
  896.                     {
  897.                         /* if save wasn't successful, then get rid of the file stuff */
  898.                         CloseFile(Window->TheFile);
  899.                         DeleteFile(Window->TheFileLocation);
  900.                         DisposeFileSpec(Window->TheFileLocation);
  901.                         Window->EverBeenSaved = False;
  902.                     }
  903.                 MainWindowDispatchNameChange(Window);
  904.                 return SaveWasSuccessful;
  905.             }
  906.          else
  907.             {
  908.                 return False;
  909.             }
  910.         EXECUTE(PRERR(ForceAbort,"SaveDocumentAs:  control reached end of function"));
  911.     }
  912.  
  913.  
  914. /* return True if the document has been modified & should be saved. */
  915. MyBoolean                        HasDocumentBeenModified(MainWindowRec* Window)
  916.     {
  917.         CheckPtrExistence(Window);
  918.         return Window->StuffModified
  919.             || TextEditDoesItNeedToBeSaved(Window->CommentInfo)
  920.             || DoesFunctionListNeedToBeSaved(Window->FunctionList)
  921.             || DoesSampleListNeedToBeSaved(Window->SampleList)
  922.             || DoesAlgoSampListNeedToBeSaved(Window->AlgoSampList)
  923.             || DoesWaveTableListNeedToBeSaved(Window->WaveTableList)
  924.             || DoesAlgoWaveTableListNeedToBeSaved(Window->AlgoWaveTableList)
  925.             || DoesInstrListNeedToBeSaved(Window->InstrumentList)
  926.             || DoesTrackListNeedToBeSaved(Window->TrackList);
  927.     }
  928.  
  929.  
  930. void                                MainWindowDoIdle(MainWindowRec* Window,
  931.                                             MyBoolean CheckCursorFlag, OrdType XLoc, OrdType YLoc,
  932.                                             ModifierFlags Modifiers)
  933.     {
  934.         CheckPtrExistence(Window);
  935.         TextEditUpdateCursor(Window->CommentInfo);
  936.         if (CheckCursorFlag)
  937.             {
  938.                 if (TextEditIBeamTest(Window->CommentInfo,XLoc,YLoc))
  939.                     {
  940.                         SetIBeamCursor();
  941.                     }
  942.                  else
  943.                     {
  944.                         SetArrowCursor();
  945.                     }
  946.             }
  947.     }
  948.  
  949.  
  950. void                                MainWindowBecomeActive(MainWindowRec* Window)
  951.     {
  952.         OrdType            XSize;
  953.         OrdType            YSize;
  954.  
  955.         CheckPtrExistence(Window);
  956.         EnableTextEditSelection(Window->CommentInfo);
  957.         FunctionListBecomeActive(Window->FunctionList);
  958.         SampleListBecomeActive(Window->SampleList);
  959.         AlgoSampListBecomeActive(Window->AlgoSampList);
  960.         WaveTableListBecomeActive(Window->WaveTableList);
  961.         AlgoWaveTableListBecomeActive(Window->AlgoWaveTableList);
  962.         InstrListBecomeActive(Window->InstrumentList);
  963.         TrackListBecomeActive(Window->TrackList);
  964.         XSize = GetWindowWidth(Window->ScreenID);
  965.         YSize = GetWindowHeight(Window->ScreenID);
  966.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  967.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,GetGrowIcon(True/*enablegrowicon*/));
  968.     }
  969.  
  970.  
  971. void                                MainWindowBecomeInactive(MainWindowRec* Window)
  972.     {
  973.         OrdType            XSize;
  974.         OrdType            YSize;
  975.  
  976.         CheckPtrExistence(Window);
  977.         DisableTextEditSelection(Window->CommentInfo);
  978.         FunctionListBecomeInactive(Window->FunctionList);
  979.         SampleListBecomeInactive(Window->SampleList);
  980.         AlgoSampListBecomeInactive(Window->AlgoSampList);
  981.         WaveTableListBecomeInactive(Window->WaveTableList);
  982.         AlgoWaveTableListBecomeInactive(Window->AlgoWaveTableList);
  983.         InstrListBecomeInactive(Window->InstrumentList);
  984.         TrackListBecomeInactive(Window->TrackList);
  985.         XSize = GetWindowWidth(Window->ScreenID);
  986.         YSize = GetWindowHeight(Window->ScreenID);
  987.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  988.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,GetGrowIcon(False/*disablegrowicon*/));
  989.     }
  990.  
  991.  
  992. void                                MainWindowJustResized(MainWindowRec* Window)
  993.     {
  994.         OrdType            XSize;
  995.         OrdType            YSize;
  996.  
  997.         CheckPtrExistence(Window);
  998.         XSize = GetWindowWidth(Window->ScreenID);
  999.         YSize = GetWindowHeight(Window->ScreenID);
  1000.         SetClipRect(Window->ScreenID,0,0,XSize,YSize);
  1001.         DrawBoxErase(Window->ScreenID,0,0,XSize,YSize);
  1002.         SetTextEditPosition(Window->CommentInfo,
  1003.             COMMENTX(XSize,YSize),COMMENTY(XSize,YSize),
  1004.             COMMENTWIDTH(XSize,YSize),COMMENTHEIGHT(XSize,YSize));
  1005.         SetFunctionListLocation(Window->FunctionList,
  1006.             FUNCTIONX(XSize,YSize),FUNCTIONY(XSize,YSize),
  1007.             FUNCTIONWIDTH(XSize,YSize),FUNCTIONHEIGHT(XSize,YSize));
  1008.         SetSampleListLocation(Window->SampleList,
  1009.             SAMPLEX(XSize,YSize),SAMPLEY(XSize,YSize),
  1010.             SAMPLEWIDTH(XSize,YSize),SAMPLEHEIGHT(XSize,YSize));
  1011.         SetAlgoSampListLocation(Window->AlgoSampList,
  1012.             ALGOSAMPLEX(XSize,YSize),ALGOSAMPLEY(XSize,YSize),
  1013.             ALGOSAMPLEWIDTH(XSize,YSize),ALGOSAMPLEHEIGHT(XSize,YSize));
  1014.         SetWaveTableListLocation(Window->WaveTableList,
  1015.             WAVETABLEX(XSize,YSize),WAVETABLEY(XSize,YSize),WAVETABLEWIDTH(XSize,YSize),
  1016.             WAVETABLEHEIGHT(XSize,YSize));
  1017.         SetAlgoWaveTableListLocation(Window->AlgoWaveTableList,
  1018.             ALGOWAVETABLEX(XSize,YSize),ALGOWAVETABLEY(XSize,YSize),
  1019.             ALGOWAVETABLEWIDTH(XSize,YSize),ALGOWAVETABLEHEIGHT(XSize,YSize));
  1020.         SetInstrListLocation(Window->InstrumentList,INSTRUMENTX(XSize,YSize),
  1021.             INSTRUMENTY(XSize,YSize),INSTRUMENTWIDTH(XSize,YSize),INSTRUMENTHEIGHT(XSize,YSize));
  1022.         SetTrackListLocation(Window->TrackList,TRACKX(XSize,YSize),TRACKY(XSize,YSize),
  1023.             TRACKWIDTH(XSize,YSize),TRACKHEIGHT(XSize,YSize));
  1024.     }
  1025.  
  1026.  
  1027. void                                MainWindowDoMouseDown(OrdType XLoc, OrdType YLoc,
  1028.                                             ModifierFlags Modifiers, MainWindowRec* Window)
  1029.     {
  1030.         CheckPtrExistence(Window);
  1031.         if ((XLoc >= GetWindowWidth(Window->ScreenID) - 15)
  1032.             && (XLoc < GetWindowWidth(Window->ScreenID))
  1033.             && (YLoc >= GetWindowHeight(Window->ScreenID) - 15)
  1034.             && (YLoc < GetWindowHeight(Window->ScreenID)))
  1035.             {
  1036.                 UserGrowWindow(Window->ScreenID,XLoc,YLoc);
  1037.                 MainWindowJustResized(Window);
  1038.             }
  1039.         else if (TextEditHitTest(Window->CommentInfo,XLoc,YLoc))
  1040.             {
  1041.                 TextEditDoMouseDown(Window->CommentInfo,XLoc,YLoc,Modifiers);
  1042.             }
  1043.         else if (FunctionListHitTest(Window->FunctionList,XLoc,YLoc))
  1044.             {
  1045.                 MainWindowDeselectAllOtherStringLists(Window,Window->FunctionList);
  1046.                 FunctionListDoMouseDown(Window->FunctionList,XLoc,YLoc,Modifiers);
  1047.             }
  1048.         else if (SampleListHitTest(Window->SampleList,XLoc,YLoc))
  1049.             {
  1050.                 MainWindowDeselectAllOtherStringLists(Window,Window->SampleList);
  1051.                 SampleListDoMouseDown(Window->SampleList,XLoc,YLoc,Modifiers);
  1052.             }
  1053.         else if (AlgoSampListHitTest(Window->AlgoSampList,XLoc,YLoc))
  1054.             {
  1055.                 MainWindowDeselectAllOtherStringLists(Window,Window->AlgoSampList);
  1056.                 AlgoSampListDoMouseDown(Window->AlgoSampList,XLoc,YLoc,Modifiers);
  1057.             }
  1058.         else if (WaveTableListHitTest(Window->WaveTableList,XLoc,YLoc))
  1059.             {
  1060.                 MainWindowDeselectAllOtherStringLists(Window,Window->WaveTableList);
  1061.                 WaveTableListDoMouseDown(Window->WaveTableList,XLoc,YLoc,Modifiers);
  1062.             }
  1063.         else if (AlgoWaveTableListHitTest(Window->AlgoWaveTableList,XLoc,YLoc))
  1064.             {
  1065.                 MainWindowDeselectAllOtherStringLists(Window,Window->AlgoWaveTableList);
  1066.                 AlgoWaveTableListDoMouseDown(Window->AlgoWaveTableList,XLoc,YLoc,Modifiers);
  1067.             }
  1068.         else if (InstrListHitTest(Window->InstrumentList,XLoc,YLoc))
  1069.             {
  1070.                 MainWindowDeselectAllOtherStringLists(Window,Window->InstrumentList);
  1071.                 InstrListDoMouseDown(Window->InstrumentList,XLoc,YLoc,Modifiers);
  1072.             }
  1073.         else if (TrackListHitTest(Window->TrackList,XLoc,YLoc))
  1074.             {
  1075.                 MainWindowDeselectAllOtherStringLists(Window,Window->TrackList);
  1076.                 TrackListDoMouseDown(Window->TrackList,XLoc,YLoc,Modifiers);
  1077.             }
  1078.     }
  1079.  
  1080.  
  1081. void                                MainWindowDoKeyDown(unsigned char KeyCode, ModifierFlags Modifiers,
  1082.                                             MainWindowRec* Window)
  1083.     {
  1084.         CheckPtrExistence(Window);
  1085.         TextEditDoKeyPressed(Window->CommentInfo,KeyCode,Modifiers);
  1086.     }
  1087.  
  1088.  
  1089. void                                MainWindowClose(MainWindowRec* Window)
  1090.     {
  1091.         CheckPtrExistence(Window);
  1092.         CloseDocument(Window);
  1093.     }
  1094.  
  1095.  
  1096. void                                MainWindowUpdator(MainWindowRec* Window)
  1097.     {
  1098.         OrdType                        XSize;
  1099.         OrdType                        YSize;
  1100.  
  1101.         CheckPtrExistence(Window);
  1102.         FunctionListRedraw(Window->FunctionList);
  1103.         SampleListRedraw(Window->SampleList);
  1104.         AlgoSampListRedraw(Window->AlgoSampList);
  1105.         WaveTableListRedraw(Window->WaveTableList);
  1106.         AlgoWaveTableListRedraw(Window->AlgoWaveTableList);
  1107.         InstrListRedraw(Window->InstrumentList);
  1108.         TrackListRedraw(Window->TrackList);
  1109.         TextEditFullRedraw(Window->CommentInfo);
  1110.         XSize = GetWindowWidth(Window->ScreenID);
  1111.         YSize = GetWindowHeight(Window->ScreenID);
  1112.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  1113.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,
  1114.             GetGrowIcon(Window->MyGenericWindow == GetCurrentWindowID()));
  1115.     }
  1116.  
  1117.  
  1118. /* enable global menu items.  these are menu items that can be chosen regardless */
  1119. /* of which editor is open (such as New Object, Save...) */
  1120. void                                MainWindowMenuSetup(MainWindowRec* Window)
  1121.     {
  1122.         MainWindowEnableGlobalMenus(Window);
  1123.         EnableMenuItem(mPaste);
  1124.         if (TextEditIsThereValidSelection(Window->CommentInfo))
  1125.             {
  1126.                 EnableMenuItem(mCut);
  1127.                 EnableMenuItem(mCopy);
  1128.                 EnableMenuItem(mClear);
  1129.             }
  1130.         EnableMenuItem(mSelectAll);
  1131.         if (TextEditCanWeUndo(Window->CommentInfo))
  1132.             {
  1133.                 EnableMenuItem(mUndo);
  1134.                 ChangeItemName(mUndo,"Undo Text Edit");
  1135.             }
  1136.         if (Window->DeleteUndoFileLocation != NIL)
  1137.             {
  1138.                 EnableMenuItem(mUndo);
  1139.                 ChangeItemName(mUndo,"Undo Object Deletion");
  1140.             }
  1141.         ChangeItemName(mCloseFile,"Close Document");
  1142.         EnableMenuItem(mCloseFile);
  1143.  
  1144.         EnableMenuItem(mEditScoreEffects);
  1145.         EnableMenuItem(mPasteObject);
  1146.         EnableMenuItem(mCopyObject);
  1147.         EnableMenuItem(mOpenObject);
  1148.         EnableMenuItem(mDeleteObject);
  1149.         if (FunctionListIsThereSelection(Window->FunctionList))
  1150.             {
  1151.                 ChangeItemName(mOpenObject,"Edit Function Module");
  1152.                 ChangeItemName(mDeleteObject,"Delete Function Module");
  1153.                 ChangeItemName(mCopyObject,"Copy Function Module");
  1154.             }
  1155.         else if (SampleListIsThereSelection(Window->SampleList))
  1156.             {
  1157.                 ChangeItemName(mOpenObject,"Edit Sample");
  1158.                 ChangeItemName(mDeleteObject,"Delete Sample");
  1159.                 ChangeItemName(mCopyObject,"Copy Sample");
  1160.             }
  1161.         else if (AlgoSampListIsThereSelection(Window->AlgoSampList))
  1162.             {
  1163.                 ChangeItemName(mOpenObject,"Edit Algorithmic Sample");
  1164.                 ChangeItemName(mDeleteObject,"Delete Algorithmic Sample");
  1165.                 ChangeItemName(mCopyObject,"Copy Algorithmic Sample");
  1166.             }
  1167.         else if (WaveTableListIsThereSelection(Window->WaveTableList))
  1168.             {
  1169.                 ChangeItemName(mOpenObject,"Edit Wave Table");
  1170.                 ChangeItemName(mDeleteObject,"Delete Wave Table");
  1171.                 ChangeItemName(mCopyObject,"Copy Wave Table");
  1172.             }
  1173.         else if (AlgoWaveTableListIsThereSelection(Window->AlgoWaveTableList))
  1174.             {
  1175.                 ChangeItemName(mOpenObject,"Edit Algorithmic Wave Table");
  1176.                 ChangeItemName(mDeleteObject,"Delete Algorithmic Wave Table");
  1177.                 ChangeItemName(mCopyObject,"Copy Algorithmic Wave Table");
  1178.             }
  1179.         else if (InstrListIsThereSelection(Window->InstrumentList))
  1180.             {
  1181.                 ChangeItemName(mOpenObject,"Edit Instrument");
  1182.                 ChangeItemName(mDeleteObject,"Delete Instrument");
  1183.                 ChangeItemName(mCopyObject,"Copy Instrument");
  1184.             }
  1185.         else if (TrackListIsThereSelection(Window->TrackList))
  1186.             {
  1187.                 ChangeItemName(mOpenObject,"Edit Track");
  1188.                 ChangeItemName(mDeleteObject,"Delete Track");
  1189.                 ChangeItemName(mCopyObject,"Copy Track");
  1190.             }
  1191.         else
  1192.             {
  1193.                 DisableMenuItem(mOpenObject);
  1194.                 DisableMenuItem(mDeleteObject);
  1195.                 DisableMenuItem(mCopyObject);
  1196.             }
  1197.         SetItemCheckmark(Window->MyMenuItem);
  1198.     }
  1199.  
  1200.  
  1201. void                                MainWindowDoMenuCommand(MainWindowRec* Window,
  1202.                                             MenuItemType* MenuItem)
  1203.     {
  1204.         CheckPtrExistence(Window);
  1205.         if (MainWindowDoGlobalMenuItem(Window,MenuItem))
  1206.             {
  1207.             }
  1208.         else if (MenuItem == mPaste)
  1209.             {
  1210.                 TextEditDoMenuPaste(Window->CommentInfo);
  1211.             }
  1212.         else if (MenuItem == mCut)
  1213.             {
  1214.                 TextEditDoMenuCut(Window->CommentInfo);
  1215.             }
  1216.         else if (MenuItem == mCopy)
  1217.             {
  1218.                 TextEditDoMenuCopy(Window->CommentInfo);
  1219.             }
  1220.         else if (MenuItem == mClear)
  1221.             {
  1222.                 TextEditDoMenuClear(Window->CommentInfo);
  1223.             }
  1224.         else if (MenuItem == mSelectAll)
  1225.             {
  1226.                 TextEditDoMenuSelectAll(Window->CommentInfo);
  1227.             }
  1228.         else if (MenuItem == mEditScoreEffects)
  1229.             {
  1230.                 MainWindowOpenScoreEffectWindow(Window);
  1231.             }
  1232.         else if (MenuItem == mUndo)
  1233.             {
  1234.                 /* object deletion undo takes precedence */
  1235.                 if (Window->DeleteUndoFileLocation != NIL)
  1236.                     {
  1237.                         MyBoolean                    DidIt = True;
  1238.  
  1239.                         SetWatchCursor();
  1240.                         if (!FunctionListPasteFromFile(Window->FunctionList,
  1241.                             Window->DeleteUndoFile))
  1242.                             {
  1243.                                 if (!SampleListPasteFromFile(Window->SampleList,
  1244.                                     Window->DeleteUndoFile))
  1245.                                     {
  1246.                                         if (!AlgoSampListPasteFromFile(Window->AlgoSampList,
  1247.                                             Window->DeleteUndoFile))
  1248.                                             {
  1249.                                                 if (!WaveTableListPasteFromFile(Window->WaveTableList,
  1250.                                                     Window->DeleteUndoFile))
  1251.                                                     {
  1252.                                                         if (!AlgoWaveTableListPasteFromFile(Window->AlgoWaveTableList,
  1253.                                                             Window->DeleteUndoFile))
  1254.                                                             {
  1255.                                                                 if (!InstrListPasteFromFile(Window->InstrumentList,
  1256.                                                                     Window->DeleteUndoFile))
  1257.                                                                     {
  1258.                                                                         if (!TrackListPasteFromFile(Window->TrackList,
  1259.                                                                             Window->DeleteUndoFile))
  1260.                                                                             {
  1261.                                                                                 /* couldn't do it, maybe out of memory */
  1262.                                                                                 DidIt = False;
  1263.                                                                             }
  1264.                                                                     }
  1265.                                                             }
  1266.                                                     }
  1267.                                             }
  1268.                                     }
  1269.                             }
  1270.                         if (DidIt)
  1271.                             {
  1272.                                 CloseFile(Window->DeleteUndoFile);
  1273.                                 DeleteFile(Window->DeleteUndoFileLocation);
  1274.                                 DisposeFileSpec(Window->DeleteUndoFileLocation);
  1275.                                 Window->DeleteUndoFileLocation = NIL;
  1276.                                 Window->DeleteUndoFile = NIL;
  1277.                             }
  1278.                     }
  1279.                  else
  1280.                     {
  1281.                         TextEditDoMenuUndo(Window->CommentInfo);
  1282.                     }
  1283.             }
  1284.         else if (MenuItem == mCloseFile)
  1285.             {
  1286.                 CloseDocument(Window);
  1287.             }
  1288.         else if (MenuItem == mOpenObject)
  1289.             {
  1290.                 if (FunctionListIsThereSelection(Window->FunctionList))
  1291.                     {
  1292.                         FunctionListOpenSelection(Window->FunctionList);
  1293.                     }
  1294.                 else if (SampleListIsThereSelection(Window->SampleList))
  1295.                     {
  1296.                         SampleListOpenSelection(Window->SampleList);
  1297.                     }
  1298.                 else if (AlgoSampListIsThereSelection(Window->AlgoSampList))
  1299.                     {
  1300.                         AlgoSampListOpenSelection(Window->AlgoSampList);
  1301.                     }
  1302.                 else if (WaveTableListIsThereSelection(Window->WaveTableList))
  1303.                     {
  1304.                         WaveTableListOpenSelection(Window->WaveTableList);
  1305.                     }
  1306.                 else if (AlgoWaveTableListIsThereSelection(Window->AlgoWaveTableList))
  1307.                     {
  1308.                         AlgoWaveTableListOpenSelection(Window->AlgoWaveTableList);
  1309.                     }
  1310.                 else if (InstrListIsThereSelection(Window->InstrumentList))
  1311.                     {
  1312.                         InstrListOpenSelection(Window->InstrumentList);
  1313.                     }
  1314.                 else if (TrackListIsThereSelection(Window->TrackList))
  1315.                     {
  1316.                         TrackListOpenSelection(Window->TrackList);
  1317.                     }
  1318.                 else
  1319.                     {
  1320.                         EXECUTE(PRERR(AllowResume,
  1321.                             "MainWindowDoMenuCommand(mOpenObject):  no known selection"));
  1322.                     }
  1323.             }
  1324.         else if (MenuItem == mDeleteObject)
  1325.             {
  1326.                 if (FunctionListIsThereSelection(Window->FunctionList))
  1327.                     {
  1328.                         FunctionListDeleteSelection(Window->FunctionList);
  1329.                     }
  1330.                 else if (SampleListIsThereSelection(Window->SampleList))
  1331.                     {
  1332.                         SampleListDeleteSelection(Window->SampleList);
  1333.                     }
  1334.                 else if (AlgoSampListIsThereSelection(Window->AlgoSampList))
  1335.                     {
  1336.                         AlgoSampListDeleteSelection(Window->AlgoSampList);
  1337.                     }
  1338.                 else if (WaveTableListIsThereSelection(Window->WaveTableList))
  1339.                     {
  1340.                         WaveTableListDeleteSelection(Window->WaveTableList);
  1341.                     }
  1342.                 else if (AlgoWaveTableListIsThereSelection(Window->AlgoWaveTableList))
  1343.                     {
  1344.                         AlgoWaveTableListDeleteSelection(Window->AlgoWaveTableList);
  1345.                     }
  1346.                 else if (InstrListIsThereSelection(Window->InstrumentList))
  1347.                     {
  1348.                         InstrListDeleteSelection(Window->InstrumentList);
  1349.                     }
  1350.                 else if (TrackListIsThereSelection(Window->TrackList))
  1351.                     {
  1352.                         TrackListDeleteSelection(Window->TrackList);
  1353.                     }
  1354.                 else
  1355.                     {
  1356.                         EXECUTE(PRERR(AllowResume,
  1357.                             "MainWindowDoMenuCommand(mDeleteObject):  no known selection"));
  1358.                     }
  1359.             }
  1360.         else if (MenuItem == mPasteObject)
  1361.             {
  1362.                 if (!FunctionListPasteObject(Window->FunctionList))
  1363.                     {
  1364.                         if (!SampleListPasteObject(Window->SampleList))
  1365.                             {
  1366.                                 if (!AlgoSampListPasteObject(Window->AlgoSampList))
  1367.                                     {
  1368.                                         if (!WaveTableListPasteObject(Window->WaveTableList))
  1369.                                             {
  1370.                                                 if (!AlgoWaveTableListPasteObject(Window->AlgoWaveTableList))
  1371.                                                     {
  1372.                                                         if (!InstrListPasteObject(Window->InstrumentList))
  1373.                                                             {
  1374.                                                                 if (!TrackListPasteObject(Window->TrackList))
  1375.                                                                     {
  1376.                                                                         /* oh well, it must not be an object */
  1377.                                                                     }
  1378.                                                             }
  1379.                                                     }
  1380.                                             }
  1381.                                     }
  1382.                             }
  1383.                     }
  1384.             }
  1385.         else if (MenuItem == mCopyObject)
  1386.             {
  1387.                 if (FunctionListIsThereSelection(Window->FunctionList))
  1388.                     {
  1389.                         FunctionListCopyObject(Window->FunctionList);
  1390.                     }
  1391.                 else if (SampleListIsThereSelection(Window->SampleList))
  1392.                     {
  1393.                         SampleListCopyObject(Window->SampleList);
  1394.                     }
  1395.                 else if (AlgoSampListIsThereSelection(Window->AlgoSampList))
  1396.                     {
  1397.                         AlgoSampListCopyObject(Window->AlgoSampList);
  1398.                     }
  1399.                 else if (WaveTableListIsThereSelection(Window->WaveTableList))
  1400.                     {
  1401.                         WaveTableListCopyObject(Window->WaveTableList);
  1402.                     }
  1403.                 else if (AlgoWaveTableListIsThereSelection(Window->AlgoWaveTableList))
  1404.                     {
  1405.                         AlgoWaveTableListCopyObject(Window->AlgoWaveTableList);
  1406.                     }
  1407.                 else if (InstrListIsThereSelection(Window->InstrumentList))
  1408.                     {
  1409.                         InstrListCopyObject(Window->InstrumentList);
  1410.                     }
  1411.                 else if (TrackListIsThereSelection(Window->TrackList))
  1412.                     {
  1413.                         TrackListCopyObject(Window->TrackList);
  1414.                     }
  1415.                 else
  1416.                     {
  1417.                         EXECUTE(PRERR(AllowResume,
  1418.                             "MainWindowDoMenuCommand(mCopyObject):  no known selection"));
  1419.                     }
  1420.             }
  1421.         else
  1422.             {
  1423.                 EXECUTE(PRERR(AllowResume,"MainWindowDoMenuCommand:  unknown menu command"));
  1424.             }
  1425.     }
  1426.  
  1427.  
  1428. /* deselect any selection in a scrolling list other than the specified list. */
  1429. /* specified list may be NIL for unconditional deselect */
  1430. void                                MainWindowDeselectAllOtherStringLists(MainWindowRec* Window,
  1431.                                             void* TheDontDeselectStringList)
  1432.     {
  1433.         CheckPtrExistence(Window);
  1434.         if (TheDontDeselectStringList != Window->FunctionList)
  1435.             {
  1436.                 FunctionListDeselect(Window->FunctionList);
  1437.             }
  1438.         if (TheDontDeselectStringList != Window->SampleList)
  1439.             {
  1440.                 SampleListDeselect(Window->SampleList);
  1441.             }
  1442.         if (TheDontDeselectStringList != Window->AlgoSampList)
  1443.             {
  1444.                 AlgoSampListDeselect(Window->AlgoSampList);
  1445.             }
  1446.         if (TheDontDeselectStringList != Window->WaveTableList)
  1447.             {
  1448.                 WaveTableListDeselect(Window->WaveTableList);
  1449.             }
  1450.         if (TheDontDeselectStringList != Window->AlgoWaveTableList)
  1451.             {
  1452.                 AlgoWaveTableListDeselect(Window->AlgoWaveTableList);
  1453.             }
  1454.         if (TheDontDeselectStringList != Window->InstrumentList)
  1455.             {
  1456.                 InstrListDeselect(Window->InstrumentList);
  1457.             }
  1458.         if (TheDontDeselectStringList != Window->TrackList)
  1459.             {
  1460.                 TrackListDeselect(Window->TrackList);
  1461.             }
  1462.     }
  1463.  
  1464.  
  1465. /* create a new calculator window.  the main window keeps track of all calculator */
  1466. /* objects that it has created */
  1467. void                                MainWindowNewCalculator(MainWindowRec* Window)
  1468.     {
  1469.         CalcWindowRec*        Calc;
  1470.  
  1471.         CheckPtrExistence(Window);
  1472.         Calc = NewCalculatorWindow(Window,Window->CodeCenter);
  1473.         if (Calc == NIL)
  1474.             {
  1475.              FailurePoint1:
  1476.                 AlertHalt("There is not enough memory available to "
  1477.                     "open a calculator window.",NIL);
  1478.                 return;
  1479.             }
  1480.         if (!ArrayAppendElement(Window->ListOfCalcWindows,Calc))
  1481.             {
  1482.              FailurePoint2:
  1483.                 DisposeCalculatorWindow(Calc);
  1484.                 goto FailurePoint1;
  1485.             }
  1486.     }
  1487.  
  1488.  
  1489. /* when a calculator window closes, it calls this to make sure the main window */
  1490. /* object knows that it no longer exists */
  1491. void                                MainWindowCalculatorClosingNotify(MainWindowRec* Window,
  1492.                                             CalcWindowRec* Calc)
  1493.     {
  1494.         CheckPtrExistence(Window);
  1495.         ERROR(ArrayFindElement(Window->ListOfCalcWindows,Calc) < 0,PRERR(ForceAbort,
  1496.             "MainWindowCalculatorClosingNotify:  unknown calculator window"));
  1497.         ArrayDeleteElement(Window->ListOfCalcWindows,
  1498.             ArrayFindElement(Window->ListOfCalcWindows,Calc));
  1499.     }
  1500.  
  1501.  
  1502. /* create an interaction window or return the current interaction window if one */
  1503. /* already exists. */
  1504. struct InteractionWindowRec*    MainWindowGetInteractionWindow(MainWindowRec* Window)
  1505.     {
  1506.         CheckPtrExistence(Window);
  1507.         if (Window->InteractionWindow == NIL)
  1508.             {
  1509.                 Window->InteractionWindow = NewInteractionWindow(Window);
  1510.                 /* if still NIL, then there isn't enough memory */
  1511.             }
  1512.         return Window->InteractionWindow;
  1513.     }
  1514.  
  1515.  
  1516. /* notify the main window that the interaction window has closed. */
  1517. void                                MainWindowInteractionClosingNotify(MainWindowRec* Window,
  1518.                                             struct InteractionWindowRec* Interaction)
  1519.     {
  1520.         CheckPtrExistence(Window);
  1521.         CheckPtrExistence(Interaction);
  1522.         ERROR(Interaction != Window->InteractionWindow,PRERR(ForceAbort,
  1523.             "MainWindowInteractionClosingNotify:  invalid interaction"));
  1524.         Window->InteractionWindow = NIL;
  1525.     }
  1526.  
  1527.  
  1528. /* notify the main window that a new disassembly window has been created. */
  1529. MyBoolean                        MainWindowNewDisassemblyNotify(MainWindowRec* Window,
  1530.                                             struct DisaWindowRec* DisassemblyWindow)
  1531.     {
  1532.         CheckPtrExistence(Window);
  1533.         if (!ArrayAppendElement(Window->ListOfDisassemblies,DisassemblyWindow))
  1534.             {
  1535.                 return False;
  1536.             }
  1537.         return True;
  1538.     }
  1539.  
  1540.  
  1541. /* notify the main window that a disassembly window has been destroyed. */
  1542. void                                MainWindowDisassemblyClosingNotify(MainWindowRec* Window,
  1543.                                             struct DisaWindowRec* DisassemblyWindow)
  1544.     {
  1545.         CheckPtrExistence(Window);
  1546.         ERROR(ArrayFindElement(Window->ListOfDisassemblies,DisassemblyWindow) < 0,
  1547.             PRERR(ForceAbort,"MainWindowDisassemblyClosingNotify:  unknown disassembly"));
  1548.         ArrayDeleteElement(Window->ListOfDisassemblies,
  1549.             ArrayFindElement(Window->ListOfDisassemblies,DisassemblyWindow));
  1550.     }
  1551.  
  1552.  
  1553. /* get the number of spaces per tab that editors should use */
  1554. long                                MainWindowGetTabSize(MainWindowRec* Window)
  1555.     {
  1556.         CheckPtrExistence(Window);
  1557.         return Window->TabSize;
  1558.     }
  1559.  
  1560.  
  1561. /* build any function objects that need to be built.  returns True if all of them */
  1562. /* were built without a problem. */
  1563. MyBoolean                        MainWindowMakeUpToDateFunctions(MainWindowRec* Window)
  1564.     {
  1565.         CheckPtrExistence(Window);
  1566.         return FunctionListMakeUpToDate(Window->FunctionList);
  1567.     }
  1568.  
  1569.  
  1570. /* build any algorithmic samples that need to be built.  returns True if all of them */
  1571. /* were built without a problem. */
  1572. MyBoolean                        MainWindowMakeUpToDateAlgoSamps(MainWindowRec* Window)
  1573.     {
  1574.         CheckPtrExistence(Window);
  1575.         return AlgoSampListMakeUpToDate(Window->AlgoSampList);
  1576.     }
  1577.  
  1578.  
  1579. /* build any algorithmic wave tables that need to be built.  returns True if all of */
  1580. /* them were built without a problem. */
  1581. MyBoolean                        MainWindowMakeUpToDateAlgoWaveTables(MainWindowRec* Window)
  1582.     {
  1583.         CheckPtrExistence(Window);
  1584.         return AlgoWaveTableListMakeUpToDate(Window->AlgoWaveTableList);
  1585.     }
  1586.  
  1587.  
  1588. /* build any instrument specifications that need to be built.  returns True if all of */
  1589. /* them were built without a problem. */
  1590. MyBoolean                        MainWindowMakeUpToDateInstrList(MainWindowRec* Window)
  1591.     {
  1592.         CheckPtrExistence(Window);
  1593.         return InstrListMakeUpToDate(Window->InstrumentList);
  1594.     }
  1595.  
  1596.  
  1597. /* build everything.  returns True if everything built correctly */
  1598. MyBoolean                        MainWindowMakeEverythingUpToDate(MainWindowRec* Window)
  1599.     {
  1600.         MyBoolean                    ReturnValue;
  1601.  
  1602.         CheckPtrExistence(Window);
  1603.         ReturnValue = False;
  1604.         SetWatchCursor();
  1605.         if (MainWindowMakeUpToDateFunctions(Window))
  1606.             {
  1607.                 if (MainWindowMakeUpToDateAlgoSamps(Window))
  1608.                     {
  1609.                         if (MainWindowMakeUpToDateAlgoWaveTables(Window))
  1610.                             {
  1611.                                 if (MainWindowMakeUpToDateInstrList(Window))
  1612.                                     {
  1613.                                         EffectSpecListRec*        EffectSpec;
  1614.                         
  1615.                                         EffectSpec = MainWindowGetScoreEffectsSpec(Window);
  1616.                                         if (EffectSpec != NIL)
  1617.                                             {
  1618.                                                 /* this last one is just to check syntax */
  1619.                                                 DisposeEffectSpecList(EffectSpec);
  1620.                                                 ReturnValue = True;
  1621.                                             }
  1622.                                     }
  1623.                             }
  1624.                     }
  1625.             }
  1626.         return ReturnValue;
  1627.     }
  1628.  
  1629.  
  1630. void                                MainWindowEnableGlobalMenus(MainWindowRec* Window)
  1631.     {
  1632.         char*                            StrNumber;
  1633.  
  1634.         CheckPtrExistence(Window);
  1635.         EnableMenuItem(mSaveAs);
  1636.         if (HasDocumentBeenModified(Window) || !Window->EverBeenSaved)
  1637.             {
  1638.                 EnableMenuItem(mSaveFile);
  1639.             }
  1640.         EnableMenuItem(mNewFunction);
  1641.         EnableMenuItem(mNewSample);
  1642.         EnableMenuItem(mNewAlgoSample);
  1643.         EnableMenuItem(mNewWaveTable);
  1644.         EnableMenuItem(mNewAlgoWaveTable);
  1645.         EnableMenuItem(mNewInstrument);
  1646.         EnableMenuItem(mNewTrack);
  1647.         EnableMenuItem(mUnbuildAllFunctions);
  1648.         EnableMenuItem(mBuildEntireProject);
  1649.         EnableMenuItem(mCalculator);
  1650.         EnableMenuItem(mSetTabSize);
  1651.         EnableMenuItem(mPlay);
  1652.  
  1653.         StrNumber = IntegerToString(Window->TabSize);
  1654.         if (StrNumber != NIL)
  1655.             {
  1656.                 char*                            StrKey;
  1657.  
  1658.                 StrKey = StringToBlockCopy("_");
  1659.                 if (StrKey != NIL)
  1660.                     {
  1661.                         char*                            StrValue;
  1662.  
  1663.                         StrValue = StringToBlockCopy("Set Tab Size... (_)");
  1664.                         if (StrValue != NIL)
  1665.                             {
  1666.                                 char*                            StrResult;
  1667.  
  1668.                                 StrResult = ReplaceBlockCopy(StrValue,StrKey,StrNumber);
  1669.                                 if (StrResult != NIL)
  1670.                                     {
  1671.                                         char*                            Temp;
  1672.  
  1673.                                         Temp = BlockToStringCopy(StrResult);
  1674.                                         if (Temp != NIL)
  1675.                                             {
  1676.                                                 ReleasePtr(StrResult);
  1677.                                                 StrResult = Temp;
  1678.                                                 ChangeItemName(mSetTabSize,StrResult);
  1679.                                             }
  1680.                                         ReleasePtr(StrResult);
  1681.                                     }
  1682.                                 ReleasePtr(StrValue);
  1683.                             }
  1684.                         ReleasePtr(StrKey);
  1685.                     }
  1686.                 ReleasePtr(StrNumber);
  1687.             }
  1688.  
  1689.         EnableMenuItem(mImportWAVFormat);
  1690.         EnableMenuItem(mImportRAWFormat);
  1691.         EnableMenuItem(mImportAIFFFormat);
  1692.  
  1693.         WindowMenuEnableItems();
  1694.     }
  1695.  
  1696.  
  1697. /* this checks to see if the menu item is a global menu item.  if it is, the */
  1698. /* associated action is performed and it returns True.  if not, then it returns */
  1699. /* False and the specific editor window must handle the menu item. */
  1700. MyBoolean                        MainWindowDoGlobalMenuItem(MainWindowRec* Window,
  1701.                                             MenuItemType* MenuItem)
  1702.     {
  1703.         CheckPtrExistence(Window);
  1704.         if (MenuItem == mSaveAs)
  1705.             {
  1706.                 SaveDocumentAs(Window);
  1707.             }
  1708.         else if (MenuItem == mSaveFile)
  1709.             {
  1710.                 SaveDocument(Window);
  1711.             }
  1712.         else if (MenuItem == mNewFunction)
  1713.             {
  1714.                 FunctionListNewModule(Window->FunctionList);
  1715.             }
  1716.         else if (MenuItem == mNewSample)
  1717.             {
  1718.                 SampleListNewSample(Window->SampleList);
  1719.             }
  1720.         else if (MenuItem == mNewAlgoSample)
  1721.             {
  1722.                 AlgoSampListNewAlgoSamp(Window->AlgoSampList);
  1723.             }
  1724.         else if (MenuItem == mNewWaveTable)
  1725.             {
  1726.                 WaveTableListNewWaveTable(Window->WaveTableList);
  1727.             }
  1728.         else if (MenuItem == mNewAlgoWaveTable)
  1729.             {
  1730.                 AlgoWaveTableListNewAlgoWaveTable(Window->AlgoWaveTableList);
  1731.             }
  1732.         else if (MenuItem == mNewInstrument)
  1733.             {
  1734.                 InstrListNewInstr(Window->InstrumentList);
  1735.             }
  1736.         else if (MenuItem == mNewTrack)
  1737.             {
  1738.                 TrackListNewTrack(Window->TrackList);
  1739.             }
  1740.         else if (MenuItem == mUnbuildAllFunctions)
  1741.             {
  1742.                 FunctionListUnbuildAll(Window->FunctionList);
  1743.                 AlgoSampListUnbuildAll(Window->AlgoSampList);
  1744.                 AlgoWaveTableListUnbuildAll(Window->AlgoWaveTableList);
  1745.                 InstrListUnbuildAll(Window->InstrumentList);
  1746.             }
  1747.         else if (MenuItem == mBuildEntireProject)
  1748.             {
  1749.                 MainWindowMakeEverythingUpToDate(Window);
  1750.             }
  1751.         else if (MenuItem == mCalculator)
  1752.             {
  1753.                 MainWindowNewCalculator(Window);
  1754.             }
  1755.         else if (MenuItem == mSetTabSize)
  1756.             {
  1757.                 Window->TabSize = DoNumberDialog("Enter new tab size:",Window->TabSize,mCut,
  1758.                     mPaste,mCopy,mUndo,mSelectAll,mClear);
  1759.                 if (Window->TabSize < MINTABCOUNT)
  1760.                     {
  1761.                         Window->TabSize = MINTABCOUNT;
  1762.                     }
  1763.                 if (Window->TabSize > MAXTABCOUNT)
  1764.                     {
  1765.                         Window->TabSize = MAXTABCOUNT;
  1766.                     }
  1767.                 Window->StuffModified = True;
  1768.                 /* we should probably have a dispatch that changes the tab size in */
  1769.                 /* all objects */
  1770.             }
  1771.         else if (MenuItem == mPlay)
  1772.             {
  1773.                 DoPlayPrefsDialog(Window,Window->TrackList);
  1774.             }
  1775.         else if (MenuItem == mImportWAVFormat)
  1776.             {
  1777.                 ImportWAVSample(Window);
  1778.             }
  1779.         else if (MenuItem == mImportRAWFormat)
  1780.             {
  1781.                 ImportRAWSample(Window);
  1782.             }
  1783.         else if (MenuItem == mImportAIFFFormat)
  1784.             {
  1785.                 ImportAIFFSample(Window);
  1786.             }
  1787.         else if (DispatchWindowMenuItem(MenuItem))
  1788.             {
  1789.                 /* no action, but fall through and return True */
  1790.             }
  1791.         else
  1792.             {
  1793.                 return False;
  1794.             }
  1795.         return True;
  1796.     }
  1797.  
  1798.  
  1799. /* get a copy of the left-channel array from a stereo sample.  an error is returned */
  1800. /* indicating the success or failure of this call.  the caller is responsible for */
  1801. /* disposing both the returned array (*DataOut) and the name string */
  1802. SampleErrors                MainWindowGetSampleLeftCopy(MainWindowRec* Window,
  1803.                                             char* NullTerminatedName, largefixedsigned** DataOut)
  1804.     {
  1805.         char*                            NameCopy;
  1806.         SampleErrors            ReturnValue;
  1807.  
  1808.         CheckPtrExistence(Window);
  1809.         NameCopy = StringToBlockCopy(NullTerminatedName);
  1810.         if (NameCopy == NIL)
  1811.             {
  1812.                 return eEvalSampleNotEnoughMemoryToCopy;
  1813.             }
  1814.         ReturnValue = SampleListGetSampleLeftFixed(Window->SampleList,NameCopy,DataOut);
  1815.         ReleasePtr(NameCopy);
  1816.         return ReturnValue;
  1817.     }
  1818.  
  1819.  
  1820. /* get a copy of the right-channel array from a stereo sample.  an error is returned */
  1821. /* indicating the success or failure of this call.  the caller is responsible for */
  1822. /* disposing both the returned array (*DataOut) and the name string */
  1823. SampleErrors                MainWindowGetSampleRightCopy(MainWindowRec* Window,
  1824.                                             char* NullTerminatedName, largefixedsigned** DataOut)
  1825.     {
  1826.         char*                            NameCopy;
  1827.         SampleErrors            ReturnValue;
  1828.  
  1829.         CheckPtrExistence(Window);
  1830.         NameCopy = StringToBlockCopy(NullTerminatedName);
  1831.         if (NameCopy == NIL)
  1832.             {
  1833.                 return eEvalSampleNotEnoughMemoryToCopy;
  1834.             }
  1835.         ReturnValue = SampleListGetSampleRightFixed(Window->SampleList,NameCopy,DataOut);
  1836.         ReleasePtr(NameCopy);
  1837.         return ReturnValue;
  1838.     }
  1839.  
  1840.  
  1841. /* get a copy of the sample array from a mono sample.  an error is returned */
  1842. /* indicating the success or failure of this call.  the caller is responsible for */
  1843. /* disposing both the returned array (*DataOut) and the name string */
  1844. SampleErrors                MainWindowGetSampleMonoCopy(MainWindowRec* Window,
  1845.                                             char* NullTerminatedName, largefixedsigned** DataOut)
  1846.     {
  1847.         char*                            NameCopy;
  1848.         SampleErrors            ReturnValue;
  1849.  
  1850.         CheckPtrExistence(Window);
  1851.         NameCopy = StringToBlockCopy(NullTerminatedName);
  1852.         if (NameCopy == NIL)
  1853.             {
  1854.                 return eEvalSampleNotEnoughMemoryToCopy;
  1855.             }
  1856.         ReturnValue = SampleListGetSampleMonoFixed(Window->SampleList,NameCopy,DataOut);
  1857.         ReleasePtr(NameCopy);
  1858.         return ReturnValue;
  1859.     }
  1860.  
  1861.  
  1862. /* get the number of frames per wave period for the specified wave table.  an error */
  1863. /* code is returned indicating success or failure.  the caller is responsible for */
  1864. /* disposing of the name string. */
  1865. SampleErrors                MainWindowGetWaveTableFrameCount(MainWindowRec* Window,
  1866.                                             char* NullTerminatedName, long* FrameCountOut)
  1867.     {
  1868.         char*                            NameCopy;
  1869.         SampleErrors            ReturnValue;
  1870.  
  1871.         CheckPtrExistence(Window);
  1872.         NameCopy = StringToBlockCopy(NullTerminatedName);
  1873.         if (NameCopy == NIL)
  1874.             {
  1875.                 return eEvalSampleNotEnoughMemoryToCopy;
  1876.             }
  1877.         ReturnValue = WaveTableListGetWaveTableFrameCount(Window->WaveTableList,
  1878.             NameCopy,FrameCountOut);
  1879.         ReleasePtr(NameCopy);
  1880.         return ReturnValue;
  1881.     }
  1882.  
  1883.  
  1884. /* get the number of tables in the specified wave table.  an error */
  1885. /* code is returned indicating success or failure.  the caller is responsible for */
  1886. /* disposing of the name string. */
  1887. SampleErrors                MainWindowGetWaveTableTableCount(MainWindowRec* Window,
  1888.                                             char* NullTerminatedName, long* TableCountOut)
  1889.     {
  1890.         char*                            NameCopy;
  1891.         SampleErrors            ReturnValue;
  1892.  
  1893.         CheckPtrExistence(Window);
  1894.         NameCopy = StringToBlockCopy(NullTerminatedName);
  1895.         if (NameCopy == NIL)
  1896.             {
  1897.                 return eEvalSampleNotEnoughMemoryToCopy;
  1898.             }
  1899.         ReturnValue = WaveTableListGetWaveTableTableCount(Window->WaveTableList,
  1900.             NameCopy,TableCountOut);
  1901.         ReleasePtr(NameCopy);
  1902.         return ReturnValue;
  1903.     }
  1904.  
  1905.  
  1906. /* get a copy of the sample array from a wave table.  an error is returned */
  1907. /* indicating the success or failure of this call.  the caller is responsible for */
  1908. /* disposing both the returned array (*DataOut) and the name string */
  1909. SampleErrors                MainWindowGetWaveTableArray(MainWindowRec* Window,
  1910.                                             char* NullTerminatedName, largefixedsigned** DataOut)
  1911.     {
  1912.         char*                            NameCopy;
  1913.         SampleErrors            ReturnValue;
  1914.  
  1915.         CheckPtrExistence(Window);
  1916.         NameCopy = StringToBlockCopy(NullTerminatedName);
  1917.         if (NameCopy == NIL)
  1918.             {
  1919.                 return eEvalSampleNotEnoughMemoryToCopy;
  1920.             }
  1921.         ReturnValue = WaveTableListGetWaveTableArray(Window->WaveTableList,NameCopy,DataOut);
  1922.         ReleasePtr(NameCopy);
  1923.         return ReturnValue;
  1924.     }
  1925.  
  1926.  
  1927. /* open a new sample editor initialized with the parameters and install the data */
  1928. /* in the array RawData into it.  this array is NOT largefixedsigned, but rather is */
  1929. /* signed char or signed short, depending on the setting of NumBits.  the caller */
  1930. /* is responsible for disposing of RawData. */
  1931. struct SampleObjectRec*    MainWindowCopyRawSampleAndOpen(MainWindowRec* Window,
  1932.                                             char* RawData, NumBitsType NumBits, NumChannelsType NumChannels,
  1933.                                             long Origin, long LoopStart1, long LoopStart2, long LoopStart3,
  1934.                                             long LoopEnd1, long LoopEnd2, long LoopEnd3, long SamplingRate,
  1935.                                             double NaturalFrequency)
  1936.     {
  1937.         CheckPtrExistence(Window);
  1938.         if (RawData != NIL)
  1939.             {
  1940.                 CheckPtrExistence(RawData);
  1941.                 return SampleListCopyRawSampleAndOpen(Window->SampleList,RawData,NumBits,
  1942.                     NumChannels,Origin,LoopStart1,LoopStart2,LoopStart3,LoopEnd1,LoopEnd2,
  1943.                     LoopEnd3,SamplingRate,NaturalFrequency);
  1944.             }
  1945.          else
  1946.             {
  1947.                 return NIL;
  1948.             }
  1949.     }
  1950.  
  1951.  
  1952. /* open a new wave table editor initialized with the parameters and install the data */
  1953. /* in the array RawData into it.  this array is not largefixedsigned, but rather is */
  1954. /* signed char or signed short, depending on the setting of NumBits.  the caller */
  1955. /* is responsible for disposing of RawData. */
  1956. struct WaveTableObjectRec*    MainWindowCopyRawWaveTableAndOpen(MainWindowRec* Window,
  1957.                                             char* RawData, NumBitsType NumBits, long NumTables,
  1958.                                             long FramesPerTable)
  1959.     {
  1960.         CheckPtrExistence(Window);
  1961.         if (RawData != NIL)
  1962.             {
  1963.                 CheckPtrExistence(RawData);
  1964.                 return WaveTableListCopyRawWaveTableAndOpen(Window->WaveTableList,RawData,
  1965.                     NumBits,NumTables,FramesPerTable);
  1966.             }
  1967.          else
  1968.             {
  1969.                 return NIL;
  1970.             }
  1971.     }
  1972.  
  1973.  
  1974. /* get a copy of the name of the current document file.  the name is a heap-allocated */
  1975. /* non-null-terminated block. */
  1976. char*                                GetCopyOfDocumentName(MainWindowRec* Window)
  1977.     {
  1978.         char*                            Filename;
  1979.  
  1980.         if (Window->EverBeenSaved)
  1981.             {
  1982.                 Filename = ExtractFileName(Window->TheFileLocation);
  1983.             }
  1984.          else
  1985.             {
  1986.                 Filename = StringToBlockCopy("Untitled");
  1987.             }
  1988.         if (Filename != NIL)
  1989.             {
  1990.                 SetTag(Filename,"GetCopyOfDocumentName");
  1991.             }
  1992.         return Filename;
  1993.     }
  1994.  
  1995.  
  1996. /* dispatch a name change event.  this tells all editors that the document title */
  1997. /* has changed, and the window titles should be updated accordingly. */
  1998. void                                MainWindowDispatchNameChange(MainWindowRec* Window)
  1999.     {
  2000.         char*                            Filename;
  2001.  
  2002.         CheckPtrExistence(Window);
  2003.         Filename = GetCopyOfDocumentName(Window);
  2004.         if (Filename != NIL)
  2005.             {
  2006.                 char*                            FilenameNullTerminated;
  2007.  
  2008.                 SampleListGlobalNameChange(Window->SampleList,Filename);
  2009.                 FunctionListGlobalNameChange(Window->FunctionList,Filename);
  2010.                 AlgoSampListGlobalNameChange(Window->AlgoSampList,Filename);
  2011.                 WaveTableListGlobalNameChange(Window->WaveTableList,Filename);
  2012.                 AlgoWaveTableListGlobalNameChange(Window->AlgoWaveTableList,Filename);
  2013.                 InstrListGlobalNameChange(Window->InstrumentList,Filename);
  2014.                 TrackListGlobalNameChange(Window->TrackList,Filename);
  2015.                 FilenameNullTerminated = BlockToStringCopy(Filename);
  2016.                 if (FilenameNullTerminated != NIL)
  2017.                     {
  2018.                         SetWindowName(Window->ScreenID,FilenameNullTerminated);
  2019.                         ChangeItemName(Window->MyMenuItem,FilenameNullTerminated);
  2020.                         ReleasePtr(FilenameNullTerminated);
  2021.                     }
  2022.                 ReleasePtr(Filename);
  2023.             }
  2024.     }
  2025.  
  2026.  
  2027. MyBoolean                        MainWindowGetStereo(MainWindowRec* Window)
  2028.     {
  2029.         CheckPtrExistence(Window);
  2030.         return Window->StereoPlayback;
  2031.     }
  2032.  
  2033.  
  2034. MyBoolean                        MainWindowGetSurround(MainWindowRec* Window)
  2035.     {
  2036.         CheckPtrExistence(Window);
  2037.         return Window->SurroundEncoding;
  2038.     }
  2039.  
  2040.  
  2041. long                                MainWindowGetSamplingRate(MainWindowRec* Window)
  2042.     {
  2043.         CheckPtrExistence(Window);
  2044.         return Window->SamplingRate;
  2045.     }
  2046.  
  2047.  
  2048. long                                MainWindowGetEnvelopeRate(MainWindowRec* Window)
  2049.     {
  2050.         CheckPtrExistence(Window);
  2051.         return Window->EnvelopeUpdateRate;
  2052.     }
  2053.  
  2054.  
  2055. double                            MainWindowGetBeatsPerMinute(MainWindowRec* Window)
  2056.     {
  2057.         CheckPtrExistence(Window);
  2058.         return LargeBCD2Double(Window->DefaultBeatsPerMinute);
  2059.     }
  2060.  
  2061.  
  2062. double                            MainWindowGetVolumeScaling(MainWindowRec* Window)
  2063.     {
  2064.         CheckPtrExistence(Window);
  2065.         return LargeBCD2Double(Window->OverallVolumeScalingFactor);
  2066.     }
  2067.  
  2068.  
  2069. OutputNumBitsType        MainWindowGetOutputNumBits(MainWindowRec* Window)
  2070.     {
  2071.         CheckPtrExistence(Window);
  2072.         return Window->OutputNumBits;
  2073.     }
  2074.  
  2075.  
  2076. MyBoolean                        MainWindowGetInterpolationOverTime(MainWindowRec* Window)
  2077.     {
  2078.         CheckPtrExistence(Window);
  2079.         return Window->InterpolateOverTime;
  2080.     }
  2081.  
  2082.  
  2083. MyBoolean                        MainWindowGetInterpolationAcrossWaves(MainWindowRec* Window)
  2084.     {
  2085.         CheckPtrExistence(Window);
  2086.         return Window->InterpolateAcrossWaves;
  2087.     }
  2088.  
  2089.  
  2090. double                            MainWindowGetScanningGap(MainWindowRec* Window)
  2091.     {
  2092.         CheckPtrExistence(Window);
  2093.         return LargeBCD2Double(Window->ScanningGap);
  2094.     }
  2095.  
  2096.  
  2097. double                            MainWindowGetBufferDuration(MainWindowRec* Window)
  2098.     {
  2099.         CheckPtrExistence(Window);
  2100.         return LargeBCD2Double(Window->BufferDuration);
  2101.     }
  2102.  
  2103.  
  2104. MyBoolean                        MainWindowGetClipWarning(MainWindowRec* Window)
  2105.     {
  2106.         CheckPtrExistence(Window);
  2107.         return Window->ClipWarning;
  2108.     }
  2109.  
  2110.  
  2111. char*                                MainWindowGetScoreEffects(MainWindowRec* Window)
  2112.     {
  2113.         char*                            StringTemp;
  2114.  
  2115.         CheckPtrExistence(Window);
  2116.         if (Window->ScoreEffectsEditWindow != NIL)
  2117.             {
  2118.                 StringTemp = ScoreEffectWindowGetText(Window->ScoreEffectsEditWindow);
  2119.             }
  2120.          else
  2121.             {
  2122.                 StringTemp = CopyPtr(Window->ScoreEffects);
  2123.             }
  2124.         if (StringTemp != NIL)
  2125.             {
  2126.                 SetTag(StringTemp,"ScoreEffects");
  2127.             }
  2128.         return StringTemp;
  2129.     }
  2130.  
  2131.  
  2132. void                                PutMainWindowStereo(MainWindowRec* Window, MyBoolean NewStereoFlag)
  2133.     {
  2134.         CheckPtrExistence(Window);
  2135.         if (Window->StereoPlayback != NewStereoFlag)
  2136.             {
  2137.                 Window->StereoPlayback = NewStereoFlag;
  2138.                 Window->StuffModified = True;
  2139.             }
  2140.     }
  2141.  
  2142.  
  2143. void                                PutMainWindowSurround(MainWindowRec* Window, MyBoolean NewSurround)
  2144.     {
  2145.         CheckPtrExistence(Window);
  2146.         if (Window->SurroundEncoding != NewSurround)
  2147.             {
  2148.                 Window->SurroundEncoding = NewSurround;
  2149.                 Window->StuffModified = True;
  2150.             }
  2151.     }
  2152.  
  2153.  
  2154. void                                PutMainWindowSamplingRate(MainWindowRec* Window,
  2155.                                             long NewSamplingRate)
  2156.     {
  2157.         CheckPtrExistence(Window);
  2158.         if (NewSamplingRate < MINSAMPLINGRATE)
  2159.             {
  2160.                 NewSamplingRate = MINSAMPLINGRATE;
  2161.             }
  2162.         if (NewSamplingRate > MAXSAMPLINGRATE)
  2163.             {
  2164.                 NewSamplingRate = MAXSAMPLINGRATE;
  2165.             }
  2166.         if (Window->SamplingRate != NewSamplingRate)
  2167.             {
  2168.                 Window->SamplingRate = NewSamplingRate;
  2169.                 Window->StuffModified = True;
  2170.             }
  2171.     }
  2172.  
  2173.  
  2174. void                                PutMainWindowEnvelopeRate(MainWindowRec* Window,
  2175.                                             long NewEnvelopeRate)
  2176.     {
  2177.         CheckPtrExistence(Window);
  2178.         if (NewEnvelopeRate < 1)
  2179.             {
  2180.                 NewEnvelopeRate = 1;
  2181.             }
  2182.         if (NewEnvelopeRate > MAXSAMPLINGRATE)
  2183.             {
  2184.                 NewEnvelopeRate = MAXSAMPLINGRATE;
  2185.             }
  2186.         if (Window->EnvelopeUpdateRate != NewEnvelopeRate)
  2187.             {
  2188.                 Window->EnvelopeUpdateRate = NewEnvelopeRate;
  2189.                 Window->StuffModified = True;
  2190.             }
  2191.     }
  2192.  
  2193.  
  2194. void                                PutMainWindowBeatsPerMinute(MainWindowRec* Window,
  2195.                                             double NewBeatsPerMinute)
  2196.     {
  2197.         LargeBCDType            BPM;
  2198.  
  2199.         CheckPtrExistence(Window);
  2200.         BPM = Double2LargeBCD(NewBeatsPerMinute);
  2201.         if (Window->DefaultBeatsPerMinute != BPM)
  2202.             {
  2203.                 Window->DefaultBeatsPerMinute = BPM;
  2204.                 Window->StuffModified = True;
  2205.             }
  2206.     }
  2207.  
  2208.  
  2209. void                                PutMainWindowVolumeScaling(MainWindowRec* Window,
  2210.                                             double NewVolumeScaling)
  2211.     {
  2212.         LargeBCDType            Vol;
  2213.  
  2214.         CheckPtrExistence(Window);
  2215.         Vol = Double2LargeBCD(NewVolumeScaling);
  2216.         if (Window->OverallVolumeScalingFactor != Vol)
  2217.             {
  2218.                 Window->OverallVolumeScalingFactor = Vol;
  2219.                 Window->StuffModified = True;
  2220.             }
  2221.     }
  2222.  
  2223.  
  2224. void                                PutMainWindowOutputNumBits(MainWindowRec* Window,
  2225.                                             OutputNumBitsType NewOutputNumBits)
  2226.     {
  2227.         CheckPtrExistence(Window);
  2228.         ERROR((NewOutputNumBits != eOutput8Bits) && (NewOutputNumBits != eOutput16Bits)
  2229.             && (NewOutputNumBits != eOutput24Bits) && (NewOutputNumBits != eOutput32Bits),
  2230.             PRERR(ForceAbort,"PutMainWindowOutputNumBits:  bad value"));
  2231.         if (Window->OutputNumBits != NewOutputNumBits)
  2232.             {
  2233.                 Window->OutputNumBits = NewOutputNumBits;
  2234.                 Window->StuffModified = True;
  2235.             }
  2236.     }
  2237.  
  2238.  
  2239. void                                PutMainWindowInterpolationOverTime(MainWindowRec* Window,
  2240.                                             MyBoolean NewInterpOverTime)
  2241.     {
  2242.         CheckPtrExistence(Window);
  2243.         if (Window->InterpolateOverTime != NewInterpOverTime)
  2244.             {
  2245.                 Window->InterpolateOverTime = NewInterpOverTime;
  2246.                 Window->StuffModified = True;
  2247.             }
  2248.     }
  2249.  
  2250.  
  2251. void                                PutMainWindowInterpolationAcrossWaves(MainWindowRec* Window,
  2252.                                             MyBoolean NewInterpAcrossWaves)
  2253.     {
  2254.         CheckPtrExistence(Window);
  2255.         if (Window->InterpolateAcrossWaves != NewInterpAcrossWaves)
  2256.             {
  2257.                 Window->InterpolateAcrossWaves = NewInterpAcrossWaves;
  2258.                 Window->StuffModified = True;
  2259.             }
  2260.     }
  2261.  
  2262.  
  2263. void                                PutMainWindowScanningGap(MainWindowRec* Window, double NewScanningGap)
  2264.     {
  2265.         LargeBCDType            Gap;
  2266.  
  2267.         CheckPtrExistence(Window);
  2268.         Gap = Double2LargeBCD(NewScanningGap);
  2269.         if (Gap != Window->ScanningGap)
  2270.             {
  2271.                 Window->ScanningGap = Gap;
  2272.                 Window->StuffModified = True;
  2273.             }
  2274.     }
  2275.  
  2276.  
  2277. void                                PutMainWindowBufferDuration(MainWindowRec* Window,
  2278.                                             double NewBufferDuration)
  2279.     {
  2280.         LargeBCDType            Buffering;
  2281.  
  2282.         CheckPtrExistence(Window);
  2283.         Buffering = Double2LargeBCD(NewBufferDuration);
  2284.         if (Buffering != Window->BufferDuration)
  2285.             {
  2286.                 Window->BufferDuration = Buffering;
  2287.                 Window->StuffModified = True;
  2288.             }
  2289.     }
  2290.  
  2291.  
  2292. void                                PutMainWindowClipWarning(MainWindowRec* Window,
  2293.                                             MyBoolean NewClipWarning)
  2294.     {
  2295.         CheckPtrExistence(Window);
  2296.         if (NewClipWarning != Window->ClipWarning)
  2297.             {
  2298.                 Window->ClipWarning = NewClipWarning;
  2299.                 Window->StuffModified = True;
  2300.             }
  2301.     }
  2302.  
  2303.  
  2304. void                                PutMainWindowScoreEffects(MainWindowRec* Window,
  2305.                                             char* NewScoreEffects)
  2306.     {
  2307.         CheckPtrExistence(Window);
  2308.         CheckPtrExistence(NewScoreEffects);
  2309.         ReleasePtr(Window->ScoreEffects);
  2310.         Window->ScoreEffects = NewScoreEffects;
  2311.         Window->StuffModified = True;
  2312.     }
  2313.  
  2314.  
  2315. /* General Information Subblock Structure: */
  2316. /*   4-byte file format version code */
  2317. /*       "Syn1" - first file format */
  2318. /*       "Syn2" - moved samples to end to help compression programs */
  2319. /*   1-byte unsigned tab size code */
  2320. /*       should be in the range of 1..255 */
  2321. /*   4-byte little endian comment text length (positive 2s complement, in bytes) */
  2322. /*   n-byte character data for comment text (line feed = 0x0a) */
  2323. /*   1-byte stereo playback flag */
  2324. /*       0 = mono */
  2325. /*       1 = stereo */
  2326. /*   1-byte surround encoding flag */
  2327. /*       0 = no surround encoding */
  2328. /*       1 = generic surround encoding */
  2329. /*   4-byte little endian output sampling rate */
  2330. /*       should be in the range of 100..65535 */
  2331. /*   4-byte little endian envelope update rate */
  2332. /*       should be in the range of 1..65535 */
  2333. /*   4-byte little endian large integer coded decimal beats per minute */
  2334. /*       large integer coded decimal is decimal * 1000000 with a */
  2335. /*       range of -1999.999999 to 1999.999999 */
  2336. /*   4-byte little endian large integer coded decimal total volume scaling factor */
  2337. /*   1-byte number of bits to output */
  2338. /*       should be 8, 16, 24, or 32 */
  2339. /*   1-byte flag for interpolation over time */
  2340. /*       0 = don't interpolate over time */
  2341. /*       1 = do interpolate over time (when resampling waveforms) */
  2342. /*   1-byte flag for interpolation across waves */
  2343. /*       0 = don't interpolate across waves */
  2344. /*       1 = do interpolate across waves (when wave table synthesis index is */
  2345. /*           not an integer) */
  2346. /*   4-byte little endian large integer coded decimal scanning gap */
  2347. /*   4-byte little endian large integer coded decimal buffer duration (in seconds) */
  2348. /*   1-byte flag for clipping warning */
  2349. /*       0 = don't warn about clipped samples */
  2350. /*       1 = do warn about clipped samples */
  2351. /*   1-byte flag for song post processing enabling */
  2352. /*       0 = don't do song postprocessing */
  2353. /*       1 = do song postprocessing */
  2354. /*   4-byte little endian length of song post processing function */
  2355. /*   n-bytes of post processing function text (line fed = 0x0a) */
  2356.  
  2357.  
  2358. /* read the general information subblock from the specified file. */
  2359. FileLoadingErrors        MainWindowReadData(MainWindowRec* Window,
  2360.                                             struct BufferedInputRec* Input, short* FormatVersionNumber)
  2361.     {
  2362.         char                            FileFormatVersion[4];
  2363.         signed long                BlockLength;
  2364.         char*                            StringTemp;
  2365.         unsigned char            BuffChar;
  2366.         signed long                SignedLong;
  2367.  
  2368.         CheckPtrExistence(Window);
  2369.         CheckPtrExistence(Input);
  2370.  
  2371.         /*   4-byte file format version code */
  2372.         /*       "Syn1" - first file format */
  2373.         /*       "Syn2" - moved samples to end to help compression programs */
  2374.         if (!ReadBufferedInput(Input,4,FileFormatVersion))
  2375.             {
  2376.                 return eFileLoadDiskError;
  2377.             }
  2378.         if (MemEqu(FileFormatVersion,"Syn1",4))
  2379.             {
  2380.                 *FormatVersionNumber = 1;
  2381.             }
  2382.         else if (MemEqu(FileFormatVersion,"Syn2",4))
  2383.             {
  2384.                 *FormatVersionNumber = 2;
  2385.             }
  2386.         else
  2387.             {
  2388.                 return eFileLoadBadFormat;
  2389.             }
  2390.  
  2391.         /*   1-byte unsigned tab size code */
  2392.         /*       should be in the range of 1..255 */
  2393.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2394.             {
  2395.                 return eFileLoadDiskError;
  2396.             }
  2397.         if (BuffChar < MINTABCOUNT)
  2398.             {
  2399.                 BuffChar = MINTABCOUNT;
  2400.             }
  2401.         if (BuffChar > MAXTABCOUNT)
  2402.             {
  2403.                 BuffChar = MAXTABCOUNT;
  2404.             }
  2405.         Window->TabSize = BuffChar;
  2406.  
  2407.         /*   4-byte little endian comment text length (in bytes) */
  2408.         if (!ReadBufferedSignedLongLittleEndian(Input,&BlockLength))
  2409.             {
  2410.                 return eFileLoadDiskError;
  2411.             }
  2412.         if (BlockLength < 0)
  2413.             {
  2414.                 return eFileLoadBadFormat;
  2415.             }
  2416.         StringTemp = AllocPtrCanFail(BlockLength,"MainWindowReadData:  comment string temp");
  2417.         if (StringTemp == NIL)
  2418.             {
  2419.                 return eFileLoadOutOfMemory;
  2420.             }
  2421.         /*   n-byte character data for comment text (line feed = 0x0a) */
  2422.         if (!ReadBufferedInput(Input,BlockLength,StringTemp))
  2423.             {
  2424.                 ReleasePtr(StringTemp);
  2425.                 return eFileLoadDiskError;
  2426.             }
  2427.         if (!TextEditNewRawData(Window->CommentInfo,StringTemp,"\x0a"))
  2428.             {
  2429.                 ReleasePtr(StringTemp);
  2430.                 return eFileLoadOutOfMemory;
  2431.             }
  2432.         TextEditHasBeenSaved(Window->CommentInfo);
  2433.         ReleasePtr(StringTemp);
  2434.  
  2435.         /*   1-byte stereo playback flag */
  2436.         /*       0 = mono */
  2437.         /*       1 = stereo */
  2438.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2439.             {
  2440.                 return eFileLoadDiskError;
  2441.             }
  2442.         if (BuffChar == 0)
  2443.             {
  2444.                 Window->StereoPlayback = False;
  2445.             }
  2446.         else if (BuffChar == 1)
  2447.             {
  2448.                 Window->StereoPlayback = True;
  2449.             }
  2450.         else
  2451.             {
  2452.                 return eFileLoadBadFormat;
  2453.             }
  2454.  
  2455.         /*   1-byte surround encoding flag */
  2456.         /*       0 = no surround encoding */
  2457.         /*       1 = dolby surround encoding */
  2458.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2459.             {
  2460.                 return eFileLoadDiskError;
  2461.             }
  2462.         if (BuffChar == 0)
  2463.             {
  2464.                 Window->SurroundEncoding = False;
  2465.             }
  2466.         else if (BuffChar == 1)
  2467.             {
  2468.                 Window->SurroundEncoding = True;
  2469.             }
  2470.         else
  2471.             {
  2472.                 return eFileLoadBadFormat;
  2473.             }
  2474.  
  2475.         /*   4-byte little endian output sampling rate */
  2476.         /*       should be in the range of 100..65535 */
  2477.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2478.             {
  2479.                 return eFileLoadDiskError;
  2480.             }
  2481.         if (SignedLong < MINSAMPLINGRATE)
  2482.             {
  2483.                 SignedLong = MINSAMPLINGRATE;
  2484.             }
  2485.         if (SignedLong > MAXSAMPLINGRATE)
  2486.             {
  2487.                 SignedLong = MAXSAMPLINGRATE;
  2488.             }
  2489.         Window->SamplingRate = SignedLong;
  2490.  
  2491.         /*   4-byte little endian envelope update rate */
  2492.         /*       should be in the range of 1..65535 */
  2493.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2494.             {
  2495.                 return eFileLoadDiskError;
  2496.             }
  2497.         if (SignedLong < 1)
  2498.             {
  2499.                 SignedLong = 1;
  2500.             }
  2501.         if (SignedLong > MAXSAMPLINGRATE)
  2502.             {
  2503.                 SignedLong = MAXSAMPLINGRATE;
  2504.             }
  2505.         Window->EnvelopeUpdateRate = SignedLong;
  2506.  
  2507.         /*   4-byte little endian large integer coded decimal beats per minute */
  2508.         /*       large integer coded decimal is decimal * 1000000 with a */
  2509.         /*       range of -1999.999999 to 1999.999999 */
  2510.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2511.             {
  2512.                 return eFileLoadDiskError;
  2513.             }
  2514.         Window->DefaultBeatsPerMinute = SignedLong;
  2515.  
  2516.         /*   4-byte little endian large integer coded total volume scaling factor */
  2517.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2518.             {
  2519.                 return eFileLoadDiskError;
  2520.             }
  2521.         Window->OverallVolumeScalingFactor = SignedLong;
  2522.  
  2523.         /*   1-byte number of bits to output */
  2524.         /*       should be 8, 16, 24, or 32 */
  2525.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2526.             {
  2527.                 return eFileLoadDiskError;
  2528.             }
  2529.         if (BuffChar == 8)
  2530.             {
  2531.                 Window->OutputNumBits = eOutput8Bits;
  2532.             }
  2533.         else if (BuffChar == 16)
  2534.             {
  2535.                 Window->OutputNumBits = eOutput16Bits;
  2536.             }
  2537.         else if (BuffChar == 24)
  2538.             {
  2539.                 Window->OutputNumBits = eOutput24Bits;
  2540.             }
  2541.         else if (BuffChar == 32)
  2542.             {
  2543.                 Window->OutputNumBits = eOutput32Bits;
  2544.             }
  2545.         else
  2546.             {
  2547.                 return eFileLoadBadFormat;
  2548.             }
  2549.  
  2550.         /*   1-byte flag for interpolation over time */
  2551.         /*       0 = don't interpolate over time */
  2552.         /*       1 = do interpolate over time (when resampling waveforms) */
  2553.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2554.             {
  2555.                 return eFileLoadDiskError;
  2556.             }
  2557.         if (BuffChar == 0)
  2558.             {
  2559.                 Window->InterpolateOverTime = False;
  2560.             }
  2561.         else if (BuffChar == 1)
  2562.             {
  2563.                 Window->InterpolateOverTime = True;
  2564.             }
  2565.         else
  2566.             {
  2567.                 return eFileLoadBadFormat;
  2568.             }
  2569.  
  2570.         /*   1-byte flag for interpolation across waves */
  2571.         /*       0 = don't interpolate across waves */
  2572.         /*       1 = do interpolate across waves (when wave table synthesis index is */
  2573.         /*           not an integer) */
  2574.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2575.             {
  2576.                 return eFileLoadDiskError;
  2577.             }
  2578.         if (BuffChar == 0)
  2579.             {
  2580.                 Window->InterpolateAcrossWaves = False;
  2581.             }
  2582.         else if (BuffChar == 1)
  2583.             {
  2584.                 Window->InterpolateAcrossWaves = True;
  2585.             }
  2586.         else
  2587.             {
  2588.                 return eFileLoadBadFormat;
  2589.             }
  2590.  
  2591.         /*   4-byte little endian large integer coded decimal scanning gap */
  2592.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2593.             {
  2594.                 return eFileLoadDiskError;
  2595.             }
  2596.         Window->ScanningGap = SignedLong;
  2597.  
  2598.         /*   4-byte little endian large integer coded decimal buffer duration (in seconds) */
  2599.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2600.             {
  2601.                 return eFileLoadDiskError;
  2602.             }
  2603.         Window->BufferDuration = SignedLong;
  2604.  
  2605.         /*   1-byte flag for clipping warning */
  2606.         /*       0 = don't warn about clipped samples */
  2607.         /*       1 = do warn about clipped samples */
  2608.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2609.             {
  2610.                 return eFileLoadDiskError;
  2611.             }
  2612.         if (BuffChar == 0)
  2613.             {
  2614.                 Window->ClipWarning = False;
  2615.             }
  2616.         else if (BuffChar == 1)
  2617.             {
  2618.                 Window->ClipWarning = True;
  2619.             }
  2620.         else
  2621.             {
  2622.                 return eFileLoadBadFormat;
  2623.             }
  2624.  
  2625.         /*   1-byte flag for song post processing enabling */
  2626.         /*       0 = don't do song postprocessing */
  2627.         /*       1 = do song postprocessing */
  2628.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2629.             {
  2630.                 return eFileLoadDiskError;
  2631.             }
  2632.         /* value is no longer used */
  2633.  
  2634.         /*   4-byte little endian length of song post processing function */
  2635.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2636.             {
  2637.                 return eFileLoadDiskError;
  2638.             }
  2639.         if (SignedLong < 0)
  2640.             {
  2641.                 return eFileLoadBadFormat;
  2642.             }
  2643.  
  2644.         /*   n-bytes of post processing function text (line fed = 0x0a) */
  2645.         StringTemp = AllocPtrCanFail(SignedLong,"ScoreEffects");
  2646.         if (StringTemp == NIL)
  2647.             {
  2648.                 return eFileLoadOutOfMemory;
  2649.             }
  2650.         if (!ReadBufferedInput(Input,SignedLong,StringTemp))
  2651.             {
  2652.                 ReleasePtr(StringTemp);
  2653.                 return eFileLoadDiskError;
  2654.             }
  2655.         ReleasePtr(Window->ScoreEffects);
  2656.         Window->ScoreEffects = StringTemp;
  2657.  
  2658.         return eFileLoadNoError;
  2659.     }
  2660.  
  2661.  
  2662. /* write the general information subblock to the specified file. */
  2663. FileLoadingErrors        MainWindowWriteData(MainWindowRec* Window,
  2664.                                             struct BufferedOutputRec* Output)
  2665.     {
  2666.         char*                            StringTemp;
  2667.  
  2668.         CheckPtrExistence(Window);
  2669.         CheckPtrExistence(Output);
  2670.  
  2671.         /*   4-byte file format version code */
  2672.         /*       "Syn1" - first file format */
  2673.         /*       "Syn2" - moved samples to end to help compression programs */
  2674.         if (!WriteBufferedOutput(Output,4,"Syn2"))
  2675.             {
  2676.                 return eFileLoadDiskError;
  2677.             }
  2678.  
  2679.         /*   1-byte unsigned tab size code */
  2680.         /*       should be in the range of 1..255 */
  2681.         if (!WriteBufferedUnsignedChar(Output,Window->TabSize))
  2682.             {
  2683.                 return eFileLoadDiskError;
  2684.             }
  2685.  
  2686.         /*   4-byte little endian comment text length (in bytes) */
  2687.         StringTemp = TextEditGetRawData(Window->CommentInfo,"\x0a");
  2688.         if (StringTemp == NIL)
  2689.             {
  2690.                 return eFileLoadOutOfMemory;
  2691.             }
  2692.         if (!WriteBufferedSignedLongLittleEndian(Output,PtrSize(StringTemp)))
  2693.             {
  2694.                 ReleasePtr(StringTemp);
  2695.                 return eFileLoadDiskError;
  2696.             }
  2697.         /*   n-byte character data for comment text (line feed = 0x0a) */
  2698.         if (!WriteBufferedOutput(Output,PtrSize(StringTemp),StringTemp))
  2699.             {
  2700.                 ReleasePtr(StringTemp);
  2701.                 return eFileLoadDiskError;
  2702.             }
  2703.         ReleasePtr(StringTemp);
  2704.  
  2705.         /*   1-byte stereo playback flag */
  2706.         /*       0 = mono */
  2707.         /*       1 = stereo */
  2708.         if (Window->StereoPlayback)
  2709.             {
  2710.                 if (!WriteBufferedUnsignedChar(Output,1))
  2711.                     {
  2712.                         return eFileLoadDiskError;
  2713.                     }
  2714.             }
  2715.          else
  2716.             {
  2717.                 if (!WriteBufferedUnsignedChar(Output,0))
  2718.                     {
  2719.                         return eFileLoadDiskError;
  2720.                     }
  2721.             }
  2722.  
  2723.         /*   1-byte surround encoding flag */
  2724.         /*       0 = no surround encoding */
  2725.         /*       1 = dolby surround encoding */
  2726.         if (Window->SurroundEncoding)
  2727.             {
  2728.                 if (!WriteBufferedUnsignedChar(Output,1))
  2729.                     {
  2730.                         return eFileLoadDiskError;
  2731.                     }
  2732.             }
  2733.          else
  2734.             {
  2735.                 if (!WriteBufferedUnsignedChar(Output,0))
  2736.                     {
  2737.                         return eFileLoadDiskError;
  2738.                     }
  2739.             }
  2740.  
  2741.         /*   4-byte little endian output sampling rate */
  2742.         /*       should be in the range of 100..65535 */
  2743.         if (!WriteBufferedSignedLongLittleEndian(Output,Window->SamplingRate))
  2744.             {
  2745.                 return eFileLoadDiskError;
  2746.             }
  2747.  
  2748.         /*   4-byte little endian envelope update rate */
  2749.         /*       should be in the range of 1..65535 */
  2750.         if (!WriteBufferedSignedLongLittleEndian(Output,Window->EnvelopeUpdateRate))
  2751.             {
  2752.                 return eFileLoadDiskError;
  2753.             }
  2754.  
  2755.         /*   4-byte little endian large integer coded decimal beats per minute */
  2756.         /*       large integer coded decimal is decimal * 1000000 with a */
  2757.         /*       range of -1999.999999 to 1999.999999 */
  2758.         if (!WriteBufferedSignedLongLittleEndian(Output,Window->DefaultBeatsPerMinute))
  2759.             {
  2760.                 return eFileLoadDiskError;
  2761.             }
  2762.  
  2763.         /*   4-byte little endian large integer coded total volume scaling factor */
  2764.         if (!WriteBufferedSignedLongLittleEndian(Output,Window->OverallVolumeScalingFactor))
  2765.             {
  2766.                 return eFileLoadDiskError;
  2767.             }
  2768.  
  2769.         /*   1-byte number of bits to output */
  2770.         /*       should be 8, 16, 24, or 32 */
  2771.         switch (Window->OutputNumBits)
  2772.             {
  2773.                 default:
  2774.                     EXECUTE(PRERR(ForceAbort,"MainWindowWriteData:  bad value in Window->OutputNumBits"));
  2775.                     break;
  2776.                 case eOutput8Bits:
  2777.                     if (!WriteBufferedUnsignedChar(Output,8))
  2778.                         {
  2779.                             return eFileLoadDiskError;
  2780.                         }
  2781.                     break;
  2782.                 case eOutput16Bits:
  2783.                     if (!WriteBufferedUnsignedChar(Output,16))
  2784.                         {
  2785.                             return eFileLoadDiskError;
  2786.                         }
  2787.                     break;
  2788.                 case eOutput24Bits:
  2789.                     if (!WriteBufferedUnsignedChar(Output,24))
  2790.                         {
  2791.                             return eFileLoadDiskError;
  2792.                         }
  2793.                     break;
  2794.                 case eOutput32Bits:
  2795.                     if (!WriteBufferedUnsignedChar(Output,32))
  2796.                         {
  2797.                             return eFileLoadDiskError;
  2798.                         }
  2799.                     break;
  2800.             }
  2801.  
  2802.         /*   1-byte flag for interpolation over time */
  2803.         /*       0 = don't interpolate over time */
  2804.         /*       1 = do interpolate over time (when resampling waveforms) */
  2805.         if (Window->InterpolateOverTime)
  2806.             {
  2807.                 if (!WriteBufferedUnsignedChar(Output,1))
  2808.                     {
  2809.                         return eFileLoadDiskError;
  2810.                     }
  2811.             }
  2812.          else
  2813.             {
  2814.                 if (!WriteBufferedUnsignedChar(Output,0))
  2815.                     {
  2816.                         return eFileLoadDiskError;
  2817.                     }
  2818.             }
  2819.  
  2820.         /*   1-byte flag for interpolation across waves */
  2821.         /*       0 = don't interpolate across waves */
  2822.         /*       1 = do interpolate across waves (when wave table synthesis index is */
  2823.         /*           not an integer) */
  2824.         if (Window->InterpolateAcrossWaves)
  2825.             {
  2826.                 if (!WriteBufferedUnsignedChar(Output,1))
  2827.                     {
  2828.                         return eFileLoadDiskError;
  2829.                     }
  2830.             }
  2831.          else
  2832.             {
  2833.                 if (!WriteBufferedUnsignedChar(Output,0))
  2834.                     {
  2835.                         return eFileLoadDiskError;
  2836.                     }
  2837.             }
  2838.  
  2839.         /*   4-byte little endian large integer coded decimal scanning gap */
  2840.         if (!WriteBufferedSignedLongLittleEndian(Output,Window->ScanningGap))
  2841.             {
  2842.                 return eFileLoadDiskError;
  2843.             }
  2844.  
  2845.         /*   4-byte little endian large integer coded decimal buffer duration (in seconds) */
  2846.         if (!WriteBufferedSignedLongLittleEndian(Output,Window->BufferDuration))
  2847.             {
  2848.                 return eFileLoadDiskError;
  2849.             }
  2850.  
  2851.         /*   1-byte flag for clipping warning */
  2852.         /*       0 = don't warn about clipped samples */
  2853.         /*       1 = do warn about clipped samples */
  2854.         if (Window->ClipWarning)
  2855.             {
  2856.                 if (!WriteBufferedUnsignedChar(Output,1))
  2857.                     {
  2858.                         return eFileLoadDiskError;
  2859.                     }
  2860.             }
  2861.          else
  2862.             {
  2863.                 if (!WriteBufferedUnsignedChar(Output,0))
  2864.                     {
  2865.                         return eFileLoadDiskError;
  2866.                     }
  2867.             }
  2868.  
  2869.         /*   1-byte flag for song post processing enabling */
  2870.         /*       0 = don't do song postprocessing */
  2871.         /*       1 = do song postprocessing */
  2872.         if (!WriteBufferedUnsignedChar(Output,1))
  2873.             {
  2874.                 return eFileLoadDiskError;
  2875.             }
  2876.         /* value of this field is no longer relevant */
  2877.  
  2878.         /*   4-byte little endian length of song post processing function */
  2879.         StringTemp = MainWindowGetScoreEffects(Window);
  2880.         if (StringTemp == NIL)
  2881.             {
  2882.                 return eFileLoadOutOfMemory;
  2883.             }
  2884.         if (!WriteBufferedSignedLongLittleEndian(Output,PtrSize(StringTemp)))
  2885.             {
  2886.                 ReleasePtr(StringTemp);
  2887.                 return eFileLoadDiskError;
  2888.             }
  2889.  
  2890.         /*   n-bytes of post processing function text (line fed = 0x0a) */
  2891.         if (!WriteBufferedOutput(Output,PtrSize(StringTemp),StringTemp))
  2892.             {
  2893.                 ReleasePtr(StringTemp);
  2894.                 return eFileLoadDiskError;
  2895.             }
  2896.         ReleasePtr(StringTemp);
  2897.  
  2898.         return eFileLoadNoError;
  2899.     }
  2900.  
  2901.  
  2902. /* get the sample list object for the specified document.  the actual thing */
  2903. /* is returned */
  2904. struct SampleListRec*    MainWindowGetSampleList(MainWindowRec* Window)
  2905.     {
  2906.         CheckPtrExistence(Window);
  2907.         return Window->SampleList;
  2908.     }
  2909.  
  2910.  
  2911. /* get the algorithmic sample list object for the specified document.  the actual */
  2912. /* thing is returned. */
  2913. struct AlgoSampListRec*    MainWindowGetAlgoSampList(MainWindowRec* Window)
  2914.     {
  2915.         CheckPtrExistence(Window);
  2916.         return Window->AlgoSampList;
  2917.     }
  2918.  
  2919.  
  2920. /* get the wave table list object for the specified document.  the actual thing */
  2921. /* is returned */
  2922. struct WaveTableListRec*    MainWindowGetWaveTableList(MainWindowRec* Window)
  2923.     {
  2924.         CheckPtrExistence(Window);
  2925.         return Window->WaveTableList;
  2926.     }
  2927.  
  2928.  
  2929. /* get the algorithmic wave table list object for the specified document.  the */
  2930. /* actual thing is returned */
  2931. struct AlgoWaveTableListRec*    MainWindowGetAlgoWaveTableList(MainWindowRec* Window)
  2932.     {
  2933.         CheckPtrExistence(Window);
  2934.         return Window->AlgoWaveTableList;
  2935.     }
  2936.  
  2937.  
  2938. /* get the instrument list object for the specified document.  the actual thing */
  2939. /* is returned */
  2940. struct InstrListRec*    MainWindowGetInstrList(MainWindowRec* Window)
  2941.     {
  2942.         CheckPtrExistence(Window);
  2943.         return Window->InstrumentList;
  2944.     }
  2945.  
  2946.  
  2947. /* this updates the object deletion undo information */
  2948. void                                MainWindowNewDeleteUndoInfo(MainWindowRec* Window,
  2949.                                             struct FileSpec* Location, struct FileType* File)
  2950.     {
  2951.         CheckPtrExistence(Window);
  2952.         CheckPtrExistence(Location);
  2953.         CheckPtrExistence(File);
  2954.         if (Window->DeleteUndoFileLocation != NIL)
  2955.             {
  2956.                 CloseFile(Window->DeleteUndoFile);
  2957.                 DeleteFile(Window->DeleteUndoFileLocation);
  2958.                 DisposeFileSpec(Window->DeleteUndoFileLocation);
  2959.             }
  2960.         Window->DeleteUndoFileLocation = Location;
  2961.         Window->DeleteUndoFile = File;
  2962.     }
  2963.  
  2964.  
  2965. /* clear instrument object code.  instruments contain references to other objects, */
  2966. /* so this function must be called any time other objects are deleted, to unbuild */
  2967. /* instruments and avoid dangling pointers. */
  2968. void                                MainWindowClearInstrObjects(MainWindowRec* Window)
  2969.     {
  2970.         CheckPtrExistence(Window);
  2971.         InstrListUnbuildAll(Window->InstrumentList);
  2972.     }
  2973.  
  2974.  
  2975. /* show the score effect window */
  2976. MyBoolean                        MainWindowOpenScoreEffectWindow(MainWindowRec* Window)
  2977.     {
  2978.         CheckPtrExistence(Window);
  2979.         if (Window->ScoreEffectsEditWindow != NIL)
  2980.             {
  2981.                 ScoreEffectWindowBringToTop(Window->ScoreEffectsEditWindow);
  2982.             }
  2983.          else
  2984.             {
  2985.                 Window->ScoreEffectsEditWindow = NewScoreEffectWindow(Window,Window->ScoreEffects);
  2986.             }
  2987.         return (Window->ScoreEffectsEditWindow != NIL);
  2988.     }
  2989.  
  2990.  
  2991. /* mark score effect window as closed */
  2992. void                                MainWindowNotifyScoreEffectWindowClosed(MainWindowRec* Window,
  2993.                                             struct ScoreEffectWindowRec* TheOne)
  2994.     {
  2995.         CheckPtrExistence(Window);
  2996.         ERROR(Window->ScoreEffectsEditWindow == NIL,PRERR(ForceAbort,
  2997.             "MainWindowNotifyScoreEffectWindowClosed:  window not open"));
  2998.         ERROR(TheOne != Window->ScoreEffectsEditWindow,PRERR(ForceAbort,
  2999.             "MainWindowNotifyScoreEffectWindowClosed:  not the same window"));
  3000.         Window->ScoreEffectsEditWindow = NIL;
  3001.     }
  3002.  
  3003.  
  3004. /* obtain the score effects specification */
  3005. struct EffectSpecListRec*    MainWindowGetScoreEffectsSpec(MainWindowRec* Window)
  3006.     {
  3007.         char*                                        Text;
  3008.         BuildInstrErrors                Error;
  3009.         long                                        ErrorLine;
  3010.         EffectSpecListRec*            EffectSpec;
  3011.  
  3012.         CheckPtrExistence(Window);
  3013.         Text = MainWindowGetScoreEffects(Window);
  3014.         if (Text == NIL)
  3015.             {
  3016.                 AlertHalt("There is not enough memory available to compile the score effects.",NIL);
  3017.              FailurePoint1:
  3018.                 return NIL;
  3019.             }
  3020.  
  3021.         Error = BuildEffectList(Text,&ErrorLine,&EffectSpec,Window->WaveTableList,
  3022.             Window->AlgoWaveTableList);
  3023.  
  3024.         if (Error != eBuildInstrNoError)
  3025.             {
  3026.                 char*                                ErrorString;
  3027.                 MyBoolean                        SuccessFlag;
  3028.  
  3029.                 MainWindowOpenScoreEffectWindow(Window);
  3030.                 SuccessFlag = False;
  3031.                 if (Window->ScoreEffectsEditWindow != NIL)
  3032.                     {
  3033.                         ScoreEffectWindowHiliteLine(Window->ScoreEffectsEditWindow,ErrorLine - 1);
  3034.                         /* figure out what the error string is */
  3035.                         ErrorString = StringFromRaw(BuildInstrGetErrorMessageText(Error));
  3036.                         if (ErrorString != NIL)
  3037.                             {
  3038.                                 char*                                NumberString;
  3039.  
  3040.                                 NumberString = IntegerToString(ErrorLine);
  3041.                                 if (NumberString != NIL)
  3042.                                     {
  3043.                                         char*                                Key;
  3044.  
  3045.                                         Key = StringToBlockCopy("_");
  3046.                                         if (Key != NIL)
  3047.                                             {
  3048.                                                 char*                                BaseMessage;
  3049.  
  3050.                                                 BaseMessage = StringFromRaw("Error on line _:  _");
  3051.                                                 if (BaseMessage != NIL)
  3052.                                                     {
  3053.                                                         char*                                FixedMessage;
  3054.         
  3055.                                                         FixedMessage = ReplaceBlockCopy(BaseMessage,Key,NumberString);
  3056.                                                         if (FixedMessage != NIL)
  3057.                                                             {
  3058.                                                                 AlertHalt(FixedMessage,ErrorString);
  3059.                                                                 ReleasePtr(FixedMessage);
  3060.                                                                 SuccessFlag = True;
  3061.                                                             }
  3062.                                                         ReleasePtr(BaseMessage);
  3063.                                                     }
  3064.                                                 ReleasePtr(Key);
  3065.                                             }
  3066.                                         ReleasePtr(NumberString);
  3067.                                     }
  3068.                                 ReleasePtr(ErrorString);
  3069.                             }
  3070.                     }
  3071.                 if (!SuccessFlag)
  3072.                     {
  3073.                         AlertHalt("An error occurred while compiling the score effects, "
  3074.                             "but there is not enough memory available to open the window.",NIL);
  3075.                     }
  3076.  
  3077.              FailurePoint2:
  3078.                 ReleasePtr(Text);
  3079.                 goto FailurePoint1;
  3080.             }
  3081.  
  3082.         ReleasePtr(Text);
  3083.         return EffectSpec;
  3084.     }
  3085.